aboutsummaryrefslogtreecommitdiff
path: root/include/clang
diff options
context:
space:
mode:
Diffstat (limited to 'include/clang')
-rw-r--r--include/clang/AST/ASTContext.h66
-rw-r--r--include/clang/AST/CanonicalType.h6
-rw-r--r--include/clang/AST/Decl.h152
-rw-r--r--include/clang/AST/DeclBase.h7
-rw-r--r--include/clang/AST/DeclCXX.h256
-rw-r--r--include/clang/AST/DeclContextInternals.h53
-rw-r--r--include/clang/AST/DeclNodes.def3
-rw-r--r--include/clang/AST/DeclObjC.h8
-rw-r--r--include/clang/AST/DeclTemplate.h12
-rw-r--r--include/clang/AST/DeclarationName.h5
-rw-r--r--include/clang/AST/Expr.h75
-rw-r--r--include/clang/AST/ExprCXX.h126
-rw-r--r--include/clang/AST/RecordLayout.h18
-rw-r--r--include/clang/AST/StmtCXX.h3
-rw-r--r--include/clang/AST/TemplateBase.h28
-rw-r--r--include/clang/AST/TemplateName.h69
-rw-r--r--include/clang/AST/Type.h47
-rw-r--r--include/clang/AST/TypeLoc.h161
-rw-r--r--include/clang/AST/TypeLocBuilder.h45
-rw-r--r--include/clang/AST/TypeLocVisitor.h2
-rw-r--r--include/clang/AST/TypeNodes.def1
-rw-r--r--include/clang/AST/TypeOrdering.h7
-rw-r--r--include/clang/Analysis/PathDiagnostic.h36
-rw-r--r--include/clang/Analysis/PathSensitive/AnalysisContext.h126
-rw-r--r--include/clang/Analysis/PathSensitive/AnalysisManager.h5
-rw-r--r--include/clang/Analysis/PathSensitive/BugType.h1
-rw-r--r--include/clang/Analysis/PathSensitive/Checker.h74
-rw-r--r--include/clang/Analysis/PathSensitive/GRExprEngine.h23
-rw-r--r--include/clang/Analysis/PathSensitive/GRState.h16
-rw-r--r--include/clang/Analysis/PathSensitive/GRTransferFuncs.h3
-rw-r--r--include/clang/Analysis/PathSensitive/MemRegion.h491
-rw-r--r--include/clang/Analysis/PathSensitive/Store.h14
-rw-r--r--include/clang/Analysis/PathSensitive/SymbolManager.h19
-rw-r--r--include/clang/Analysis/ProgramPoint.h7
-rw-r--r--include/clang/Analysis/Support/BumpVector.h2
-rw-r--r--include/clang/Basic/Builtins.def90
-rw-r--r--include/clang/Basic/BuiltinsX86.def2
-rw-r--r--include/clang/Basic/Diagnostic.h3
-rw-r--r--include/clang/Basic/DiagnosticCommonKinds.td4
-rw-r--r--include/clang/Basic/DiagnosticDriverKinds.td4
-rw-r--r--include/clang/Basic/DiagnosticFrontendKinds.td36
-rw-r--r--include/clang/Basic/DiagnosticGroups.td1
-rw-r--r--include/clang/Basic/DiagnosticLexKinds.td17
-rw-r--r--include/clang/Basic/DiagnosticParseKinds.td2
-rw-r--r--include/clang/Basic/DiagnosticSemaKinds.td107
-rw-r--r--include/clang/Basic/FileManager.h9
-rw-r--r--include/clang/Basic/IdentifierTable.h6
-rw-r--r--include/clang/Basic/LangOptions.h6
-rw-r--r--include/clang/Basic/PartialDiagnostic.h33
-rw-r--r--include/clang/Basic/SourceLocation.h8
-rw-r--r--include/clang/Basic/SourceManager.h75
-rw-r--r--include/clang/Basic/TokenKinds.def2
-rw-r--r--include/clang/Basic/TypeTraits.h3
-rw-r--r--include/clang/Driver/CC1Options.td80
-rw-r--r--include/clang/Driver/Driver.h7
-rw-r--r--include/clang/Driver/Job.h11
-rw-r--r--include/clang/Driver/OptParser.td6
-rw-r--r--include/clang/Driver/OptTable.h37
-rw-r--r--include/clang/Driver/Options.td58
-rw-r--r--include/clang/Frontend/ASTConsumers.h6
-rw-r--r--include/clang/Frontend/ASTUnit.h87
-rw-r--r--include/clang/Frontend/AnalysisConsumer.h2
-rw-r--r--include/clang/Frontend/CompilerInstance.h12
-rw-r--r--include/clang/Frontend/CompilerInvocation.h14
-rw-r--r--include/clang/Frontend/FrontendOptions.h7
-rw-r--r--include/clang/Frontend/HeaderSearchOptions.h12
-rw-r--r--include/clang/Frontend/PCHBitCodes.h4
-rw-r--r--include/clang/Frontend/PCHReader.h8
-rw-r--r--include/clang/Frontend/PCHWriter.h3
-rw-r--r--include/clang/Frontend/PreprocessorOptions.h19
-rw-r--r--include/clang/Index/CallGraph.h (renamed from include/clang/Analysis/CallGraph.h)0
-rw-r--r--include/clang/Index/Entity.h5
-rw-r--r--include/clang/Index/GlobalSelector.h5
-rw-r--r--include/clang/Lex/Lexer.h16
-rw-r--r--include/clang/Lex/Preprocessor.h43
-rw-r--r--include/clang/Parse/Action.h50
-rw-r--r--include/clang/Parse/DeclSpec.h73
-rw-r--r--include/clang/Parse/Parser.h32
-rw-r--r--include/clang/Sema/ExternalSemaSource.h3
-rw-r--r--include/clang/Sema/SemaConsumer.h3
80 files changed, 1881 insertions, 1097 deletions
diff --git a/include/clang/AST/ASTContext.h b/include/clang/AST/ASTContext.h
index 4f29e5d8a618..3fc5aabde32c 100644
--- a/include/clang/AST/ASTContext.h
+++ b/include/clang/AST/ASTContext.h
@@ -45,6 +45,8 @@ namespace clang {
class SourceManager;
class TargetInfo;
// Decls
+ class CXXMethodDecl;
+ class CXXRecordDecl;
class Decl;
class FieldDecl;
class ObjCIvarDecl;
@@ -57,6 +59,7 @@ namespace clang {
class TypeDecl;
class TypedefDecl;
class UsingDecl;
+ class UsingShadowDecl;
namespace Builtin { class Context; }
@@ -105,6 +108,9 @@ class ASTContext {
llvm::DenseMap<const RecordDecl*, const ASTRecordLayout*> ASTRecordLayouts;
llvm::DenseMap<const ObjCContainerDecl*, const ASTRecordLayout*> ObjCLayouts;
+ /// KeyFunctions - A cache mapping from CXXRecordDecls to key functions.
+ llvm::DenseMap<const CXXRecordDecl*, const CXXMethodDecl*> KeyFunctions;
+
/// \brief Mapping from ObjCContainers to their ObjCImplementations.
llvm::DenseMap<ObjCContainerDecl*, ObjCImplDecl*> ObjCImpls;
@@ -183,8 +189,10 @@ class ASTContext {
llvm::DenseMap<const VarDecl *, MemberSpecializationInfo *>
InstantiatedFromStaticDataMember;
- /// \brief Keeps track of the UnresolvedUsingDecls from which UsingDecls
- /// where created during instantiation.
+ /// \brief Keeps track of the declaration from which a UsingDecl was
+ /// created during instantiation. The source declaration is always
+ /// a UsingDecl, an UnresolvedUsingValueDecl, or an
+ /// UnresolvedUsingTypenameDecl.
///
/// For example:
/// \code
@@ -203,8 +211,10 @@ class ASTContext {
///
/// This mapping will contain an entry that maps from the UsingDecl in
/// B<int> to the UnresolvedUsingDecl in B<T>.
- llvm::DenseMap<UsingDecl *, NamedDecl *>
- InstantiatedFromUnresolvedUsingDecl;
+ llvm::DenseMap<UsingDecl *, NamedDecl *> InstantiatedFromUsingDecl;
+
+ llvm::DenseMap<UsingShadowDecl*, UsingShadowDecl*>
+ InstantiatedFromUsingShadowDecl;
llvm::DenseMap<FieldDecl *, FieldDecl *> InstantiatedFromUnnamedFieldDecl;
@@ -282,14 +292,18 @@ public:
void setInstantiatedFromStaticDataMember(VarDecl *Inst, VarDecl *Tmpl,
TemplateSpecializationKind TSK);
- /// \brief If this using decl is instantiated from an unresolved using decl,
+ /// \brief If the given using decl is an instantiation of a
+ /// (possibly unresolved) using decl from a template instantiation,
/// return it.
- NamedDecl *getInstantiatedFromUnresolvedUsingDecl(UsingDecl *UUD);
+ NamedDecl *getInstantiatedFromUsingDecl(UsingDecl *Inst);
- /// \brief Note that the using decl \p Inst is an instantiation of
- /// the unresolved using decl \p Tmpl of a class template.
- void setInstantiatedFromUnresolvedUsingDecl(UsingDecl *Inst, NamedDecl *Tmpl);
+ /// \brief Remember that the using decl \p Inst is an instantiation
+ /// of the using decl \p Pattern of a class template.
+ void setInstantiatedFromUsingDecl(UsingDecl *Inst, NamedDecl *Pattern);
+ void setInstantiatedFromUsingShadowDecl(UsingShadowDecl *Inst,
+ UsingShadowDecl *Pattern);
+ UsingShadowDecl *getInstantiatedFromUsingShadowDecl(UsingShadowDecl *Inst);
FieldDecl *getInstantiatedFromUnnamedFieldDecl(FieldDecl *Field);
@@ -380,9 +394,10 @@ public:
/// equivalent to calling T.withConst().
QualType getConstType(QualType T) { return T.withConst(); }
- /// getNoReturnType - Add the noreturn attribute to the given type which must
- /// be a FunctionType or a pointer to an allowable type or a BlockPointer.
- QualType getNoReturnType(QualType T);
+ /// getNoReturnType - Add or remove the noreturn attribute to the given type
+ /// which must be a FunctionType or a pointer to an allowable type or a
+ /// BlockPointer.
+ QualType getNoReturnType(QualType T, bool AddNoReturn = true);
/// getComplexType - Return the uniqued reference to the type for a complex
/// number with the specified element type.
@@ -569,7 +584,7 @@ public:
/// getSizeType - Return the unique type for "size_t" (C99 7.17), defined
/// in <stddef.h>. The sizeof operator requires this (C99 6.5.3.4p4).
- QualType getSizeType() const;
+ CanQualType getSizeType() const;
/// getWCharType - In C++, this returns the unique wchar_t type. In C99, this
/// returns a type compatible with the type defined in <stddef.h> as defined
@@ -735,12 +750,12 @@ public:
DeclarationName getNameForTemplate(TemplateName Name);
+ TemplateName getOverloadedTemplateName(NamedDecl * const *Begin,
+ NamedDecl * const *End);
+
TemplateName getQualifiedTemplateName(NestedNameSpecifier *NNS,
bool TemplateKeyword,
TemplateDecl *Template);
- TemplateName getQualifiedTemplateName(NestedNameSpecifier *NNS,
- bool TemplateKeyword,
- OverloadedFunctionDecl *Template);
TemplateName getDependentTemplateName(NestedNameSpecifier *NNS,
const IdentifierInfo *Name);
@@ -843,6 +858,13 @@ public:
const ASTRecordLayout &
getASTObjCImplementationLayout(const ObjCImplementationDecl *D);
+ /// getKeyFunction - Get the key function for the given record decl.
+ /// The key function is, according to the Itanium C++ ABI section 5.2.3:
+ ///
+ /// ...the first non-pure virtual function that is not inline at the point
+ /// of class definition.
+ const CXXMethodDecl *getKeyFunction(const CXXRecordDecl *RD);
+
void CollectObjCIvars(const ObjCInterfaceDecl *OI,
llvm::SmallVectorImpl<FieldDecl*> &Fields);
@@ -1108,9 +1130,9 @@ public:
void setObjCImplementation(ObjCCategoryDecl *CatD,
ObjCCategoryImplDecl *ImplD);
- /// \brief Allocate an uninitialized DeclaratorInfo.
+ /// \brief Allocate an uninitialized TypeSourceInfo.
///
- /// The caller should initialize the memory held by DeclaratorInfo using
+ /// The caller should initialize the memory held by TypeSourceInfo using
/// the TypeLoc wrappers.
///
/// \param T the type that will be the basis for type source info. This type
@@ -1119,13 +1141,13 @@ public:
///
/// \param Size the size of the type info to create, or 0 if the size
/// should be calculated based on the type.
- DeclaratorInfo *CreateDeclaratorInfo(QualType T, unsigned Size = 0);
+ TypeSourceInfo *CreateTypeSourceInfo(QualType T, unsigned Size = 0);
- /// \brief Allocate a DeclaratorInfo where all locations have been
+ /// \brief Allocate a TypeSourceInfo where all locations have been
/// initialized to a given location, which defaults to the empty
/// location.
- DeclaratorInfo *
- getTrivialDeclaratorInfo(QualType T, SourceLocation Loc = SourceLocation());
+ TypeSourceInfo *
+ getTrivialTypeSourceInfo(QualType T, SourceLocation Loc = SourceLocation());
private:
ASTContext(const ASTContext&); // DO NOT IMPLEMENT
diff --git a/include/clang/AST/CanonicalType.h b/include/clang/AST/CanonicalType.h
index 9b1187770f6a..af8d23692e19 100644
--- a/include/clang/AST/CanonicalType.h
+++ b/include/clang/AST/CanonicalType.h
@@ -172,6 +172,12 @@ inline bool operator!=(CanQual<T> x, CanQual<U> y) {
/// \brief Represents a canonical, potentially-qualified type.
typedef CanQual<Type> CanQualType;
+inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
+ CanQualType T) {
+ DB << static_cast<QualType>(T);
+ return DB;
+}
+
//----------------------------------------------------------------------------//
// Internal proxy classes used by canonical types
//----------------------------------------------------------------------------//
diff --git a/include/clang/AST/Decl.h b/include/clang/AST/Decl.h
index f7944771efce..ff2b30227860 100644
--- a/include/clang/AST/Decl.h
+++ b/include/clang/AST/Decl.h
@@ -35,17 +35,17 @@ class TypeLoc;
///
/// A client can read the relevant info using TypeLoc wrappers, e.g:
/// @code
-/// TypeLoc TL = DeclaratorInfo->getTypeLoc();
+/// TypeLoc TL = TypeSourceInfo->getTypeLoc();
/// if (PointerLoc *PL = dyn_cast<PointerLoc>(&TL))
/// PL->getStarLoc().print(OS, SrcMgr);
/// @endcode
///
-class DeclaratorInfo {
+class TypeSourceInfo {
QualType Ty;
// Contains a memory block after the class, used for type source information,
// allocated by ASTContext.
friend class ASTContext;
- DeclaratorInfo(QualType ty) : Ty(ty) { }
+ TypeSourceInfo(QualType ty) : Ty(ty) { }
public:
/// \brief Return the type wrapped by this type source info.
QualType getType() const { return Ty; }
@@ -322,18 +322,18 @@ public:
};
/// \brief Represents a ValueDecl that came out of a declarator.
-/// Contains type source information through DeclaratorInfo.
+/// Contains type source information through TypeSourceInfo.
class DeclaratorDecl : public ValueDecl {
- DeclaratorInfo *DeclInfo;
+ TypeSourceInfo *DeclInfo;
protected:
DeclaratorDecl(Kind DK, DeclContext *DC, SourceLocation L,
- DeclarationName N, QualType T, DeclaratorInfo *DInfo)
- : ValueDecl(DK, DC, L, N, T), DeclInfo(DInfo) {}
+ DeclarationName N, QualType T, TypeSourceInfo *TInfo)
+ : ValueDecl(DK, DC, L, N, T), DeclInfo(TInfo) {}
public:
- DeclaratorInfo *getDeclaratorInfo() const { return DeclInfo; }
- void setDeclaratorInfo(DeclaratorInfo *DInfo) { DeclInfo = DInfo; }
+ TypeSourceInfo *getTypeSourceInfo() const { return DeclInfo; }
+ void setTypeSourceInfo(TypeSourceInfo *TInfo) { DeclInfo = TInfo; }
SourceLocation getTypeSpecStartLoc() const;
@@ -348,15 +348,23 @@ public:
/// which it was evaluated (if any), and whether or not the statement
/// is an integral constant expression (if known).
struct EvaluatedStmt {
- EvaluatedStmt() : WasEvaluated(false), CheckedICE(false), IsICE(false) { }
+ EvaluatedStmt() : WasEvaluated(false), IsEvaluating(false), CheckedICE(false),
+ CheckingICE(false), IsICE(false) { }
/// \brief Whether this statement was already evaluated.
bool WasEvaluated : 1;
+ /// \brief Whether this statement is being evaluated.
+ bool IsEvaluating : 1;
+
/// \brief Whether we already checked whether this statement was an
/// integral constant expression.
bool CheckedICE : 1;
+ /// \brief Whether we are checking whether this statement is an
+ /// integral constant expression.
+ bool CheckingICE : 1;
+
/// \brief Whether this statement is an integral constant
/// expression. Only valid if CheckedICE is true.
bool IsICE : 1;
@@ -432,8 +440,8 @@ private:
friend class StmtIteratorBase;
protected:
VarDecl(Kind DK, DeclContext *DC, SourceLocation L, IdentifierInfo *Id,
- QualType T, DeclaratorInfo *DInfo, StorageClass SC)
- : DeclaratorDecl(DK, DC, L, Id, T, DInfo), Init(),
+ QualType T, TypeSourceInfo *TInfo, StorageClass SC)
+ : DeclaratorDecl(DK, DC, L, Id, T, TInfo), Init(),
ThreadSpecified(false), HasCXXDirectInit(false),
DeclaredInCondition(false) {
SClass = SC;
@@ -453,7 +461,7 @@ public:
static VarDecl *Create(ASTContext &C, DeclContext *DC,
SourceLocation L, IdentifierInfo *Id,
- QualType T, DeclaratorInfo *DInfo, StorageClass S);
+ QualType T, TypeSourceInfo *TInfo, StorageClass S);
virtual ~VarDecl();
virtual void Destroy(ASTContext& C);
@@ -504,23 +512,45 @@ public:
void setInit(ASTContext &C, Expr *I);
- /// \brief Note that constant evaluation has computed the given
- /// value for this variable's initializer.
- void setEvaluatedValue(ASTContext &C, const APValue &Value) const {
+ EvaluatedStmt *EnsureEvaluatedStmt() const {
EvaluatedStmt *Eval = Init.dyn_cast<EvaluatedStmt *>();
if (!Eval) {
Stmt *S = Init.get<Stmt *>();
- Eval = new (C) EvaluatedStmt;
+ Eval = new (getASTContext()) EvaluatedStmt;
Eval->Value = S;
Init = Eval;
}
+ return Eval;
+ }
+
+ /// \brief Check whether we are in the process of checking whether the
+ /// initializer can be evaluated.
+ bool isEvaluatingValue() const {
+ if (EvaluatedStmt *Eval = Init.dyn_cast<EvaluatedStmt *>())
+ return Eval->IsEvaluating;
+ return false;
+ }
+
+ /// \brief Note that we now are checking whether the initializer can be
+ /// evaluated.
+ void setEvaluatingValue() const {
+ EvaluatedStmt *Eval = EnsureEvaluatedStmt();
+ Eval->IsEvaluating = true;
+ }
+
+ /// \brief Note that constant evaluation has computed the given
+ /// value for this variable's initializer.
+ void setEvaluatedValue(const APValue &Value) const {
+ EvaluatedStmt *Eval = EnsureEvaluatedStmt();
+ Eval->IsEvaluating = false;
Eval->WasEvaluated = true;
Eval->Evaluated = Value;
}
/// \brief Return the already-evaluated value of this variable's
- /// initializer, or NULL if the value is not yet known.
+ /// initializer, or NULL if the value is not yet known. Returns pointer
+ /// to untyped APValue if the value could not be evaluated.
APValue *getEvaluatedValue() const {
if (EvaluatedStmt *Eval = Init.dyn_cast<EvaluatedStmt *>())
if (Eval->WasEvaluated)
@@ -548,17 +578,27 @@ public:
return Init.get<EvaluatedStmt *>()->IsICE;
}
- /// \brief Note that we now know whether the initializer is an
+ /// \brief Check whether we are in the process of checking the initializer
+ /// is an integral constant expression.
+ bool isCheckingICE() const {
+ if (EvaluatedStmt *Eval = Init.dyn_cast<EvaluatedStmt *>())
+ return Eval->CheckingICE;
+
+ return false;
+ }
+
+ /// \brief Note that we now are checking whether the initializer is an
/// integral constant expression.
- void setInitKnownICE(ASTContext &C, bool IsICE) const {
- EvaluatedStmt *Eval = Init.dyn_cast<EvaluatedStmt *>();
- if (!Eval) {
- Stmt *S = Init.get<Stmt *>();
- Eval = new (C) EvaluatedStmt;
- Eval->Value = S;
- Init = Eval;
- }
+ void setCheckingICE() const {
+ EvaluatedStmt *Eval = EnsureEvaluatedStmt();
+ Eval->CheckingICE = true;
+ }
+ /// \brief Note that we now know whether the initializer is an
+ /// integral constant expression.
+ void setInitKnownICE(bool IsICE) const {
+ EvaluatedStmt *Eval = EnsureEvaluatedStmt();
+ Eval->CheckingICE = false;
Eval->CheckedICE = true;
Eval->IsICE = IsICE;
}
@@ -712,7 +752,7 @@ class ImplicitParamDecl : public VarDecl {
protected:
ImplicitParamDecl(Kind DK, DeclContext *DC, SourceLocation L,
IdentifierInfo *Id, QualType Tw)
- : VarDecl(DK, DC, L, Id, Tw, /*DInfo=*/0, VarDecl::None) {}
+ : VarDecl(DK, DC, L, Id, Tw, /*TInfo=*/0, VarDecl::None) {}
public:
static ImplicitParamDecl *Create(ASTContext &C, DeclContext *DC,
SourceLocation L, IdentifierInfo *Id,
@@ -739,16 +779,16 @@ class ParmVarDecl : public VarDecl {
protected:
ParmVarDecl(Kind DK, DeclContext *DC, SourceLocation L,
- IdentifierInfo *Id, QualType T, DeclaratorInfo *DInfo,
+ IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo,
StorageClass S, Expr *DefArg)
- : VarDecl(DK, DC, L, Id, T, DInfo, S), objcDeclQualifier(OBJC_TQ_None) {
+ : VarDecl(DK, DC, L, Id, T, TInfo, S), objcDeclQualifier(OBJC_TQ_None) {
setDefaultArg(DefArg);
}
public:
static ParmVarDecl *Create(ASTContext &C, DeclContext *DC,
SourceLocation L,IdentifierInfo *Id,
- QualType T, DeclaratorInfo *DInfo,
+ QualType T, TypeSourceInfo *TInfo,
StorageClass S, Expr *DefArg);
ObjCDeclQualifier getObjCDeclQualifier() const {
@@ -822,8 +862,8 @@ public:
}
QualType getOriginalType() const {
- if (getDeclaratorInfo())
- return getDeclaratorInfo()->getType();
+ if (getTypeSourceInfo())
+ return getTypeSourceInfo()->getType();
return getType();
}
@@ -907,9 +947,9 @@ private:
protected:
FunctionDecl(Kind DK, DeclContext *DC, SourceLocation L,
- DeclarationName N, QualType T, DeclaratorInfo *DInfo,
+ DeclarationName N, QualType T, TypeSourceInfo *TInfo,
StorageClass S, bool isInline)
- : DeclaratorDecl(DK, DC, L, N, T, DInfo),
+ : DeclaratorDecl(DK, DC, L, N, T, TInfo),
DeclContext(DK),
ParamInfo(0), Body(),
SClass(S), IsInline(isInline),
@@ -936,7 +976,7 @@ public:
static FunctionDecl *Create(ASTContext &C, DeclContext *DC, SourceLocation L,
DeclarationName N, QualType T,
- DeclaratorInfo *DInfo,
+ TypeSourceInfo *TInfo,
StorageClass S = None, bool isInline = false,
bool hasWrittenPrototype = true);
@@ -1272,15 +1312,15 @@ class FieldDecl : public DeclaratorDecl {
Expr *BitWidth;
protected:
FieldDecl(Kind DK, DeclContext *DC, SourceLocation L,
- IdentifierInfo *Id, QualType T, DeclaratorInfo *DInfo,
+ IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo,
Expr *BW, bool Mutable)
- : DeclaratorDecl(DK, DC, L, Id, T, DInfo), Mutable(Mutable), BitWidth(BW) {
+ : DeclaratorDecl(DK, DC, L, Id, T, TInfo), Mutable(Mutable), BitWidth(BW) {
}
public:
static FieldDecl *Create(ASTContext &C, DeclContext *DC, SourceLocation L,
IdentifierInfo *Id, QualType T,
- DeclaratorInfo *DInfo, Expr *BW, bool Mutable);
+ TypeSourceInfo *TInfo, Expr *BW, bool Mutable);
/// isMutable - Determines whether this field is mutable (C++ only).
bool isMutable() const { return Mutable; }
@@ -1383,28 +1423,28 @@ public:
class TypedefDecl : public TypeDecl {
/// UnderlyingType - This is the type the typedef is set to.
- DeclaratorInfo *DInfo;
+ TypeSourceInfo *TInfo;
TypedefDecl(DeclContext *DC, SourceLocation L,
- IdentifierInfo *Id, DeclaratorInfo *DInfo)
- : TypeDecl(Typedef, DC, L, Id), DInfo(DInfo) {}
+ IdentifierInfo *Id, TypeSourceInfo *TInfo)
+ : TypeDecl(Typedef, DC, L, Id), TInfo(TInfo) {}
virtual ~TypedefDecl() {}
public:
static TypedefDecl *Create(ASTContext &C, DeclContext *DC,
SourceLocation L, IdentifierInfo *Id,
- DeclaratorInfo *DInfo);
+ TypeSourceInfo *TInfo);
- DeclaratorInfo *getTypeDeclaratorInfo() const {
- return DInfo;
+ TypeSourceInfo *getTypeSourceInfo() const {
+ return TInfo;
}
QualType getUnderlyingType() const {
- return DInfo->getType();
+ return TInfo->getType();
}
- void setTypeDeclaratorInfo(DeclaratorInfo *newType) {
- DInfo = newType;
+ void setTypeSourceInfo(TypeSourceInfo *newType) {
+ TInfo = newType;
}
// Implement isa/cast/dyncast/etc.
@@ -1554,6 +1594,12 @@ class EnumDecl : public TagDecl {
/// have a different type than this does.
QualType IntegerType;
+ /// PromotionType - The integer type that values of this type should
+ /// promote to. In C, enumerators are generally of an integer type
+ /// directly, but gcc-style large enumerators (and all enumerators
+ /// in C++) are of the enum type instead.
+ QualType PromotionType;
+
/// \brief If the enumeration was instantiated from an enumeration
/// within a class or function template, this pointer refers to the
/// enumeration declared within the template.
@@ -1583,7 +1629,8 @@ 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(ASTContext &C, QualType NewType,
+ QualType PromotionType);
// enumerator_iterator - Iterates through the enumerators of this
// enumeration.
@@ -1597,6 +1644,13 @@ public:
return enumerator_iterator(this->decls_end());
}
+ /// getPromotionType - Return the integer type that enumerators
+ /// should promote to.
+ QualType getPromotionType() const { return PromotionType; }
+
+ /// \brief Set the promotion type.
+ void setPromotionType(QualType T) { PromotionType = T; }
+
/// getIntegerType - Return the integer type this enum decl corresponds to.
/// This returns a null qualtype for an enum forward definition.
QualType getIntegerType() const { return IntegerType; }
diff --git a/include/clang/AST/DeclBase.h b/include/clang/AST/DeclBase.h
index e1f948fdd550..497f86347a86 100644
--- a/include/clang/AST/DeclBase.h
+++ b/include/clang/AST/DeclBase.h
@@ -91,7 +91,7 @@ public:
IDNS_Ordinary = 0x8,
IDNS_ObjCProtocol = 0x10,
IDNS_ObjCImplementation = 0x20,
- IDNS_ObjCCategoryImpl = 0x40,
+ IDNS_ObjCCategoryName = 0x40,
IDNS_OrdinaryFriend = 0x80,
IDNS_TagFriend = 0x100,
IDNS_Using = 0x200
@@ -916,6 +916,9 @@ public:
/// only happens with friends.
void addHiddenDecl(Decl *D);
+ /// @brief Removes a declaration from this context.
+ void removeDecl(Decl *D);
+
/// lookup_iterator - An iterator that provides access to the results
/// of looking up a name within this context.
typedef NamedDecl **lookup_iterator;
@@ -1003,6 +1006,8 @@ public:
static bool classof(const Name##Decl *D) { return true; }
#include "clang/AST/DeclNodes.def"
+ void dumpDeclContext() const;
+
private:
void LoadLexicalDeclsFromExternalStorage() const;
void LoadVisibleDeclsFromExternalStorage() const;
diff --git a/include/clang/AST/DeclCXX.h b/include/clang/AST/DeclCXX.h
index 990403e7dc2e..5507e99e45a9 100644
--- a/include/clang/AST/DeclCXX.h
+++ b/include/clang/AST/DeclCXX.h
@@ -88,108 +88,6 @@ namespace llvm {
namespace clang {
-/// OverloadedFunctionDecl - An instance of this class represents a
-/// set of overloaded functions. All of the functions have the same
-/// name and occur within the same scope.
-///
-/// An OverloadedFunctionDecl has no ownership over the FunctionDecl
-/// nodes it contains. Rather, the FunctionDecls are owned by the
-/// enclosing scope (which also owns the OverloadedFunctionDecl
-/// node). OverloadedFunctionDecl is used primarily to store a set of
-/// overloaded functions for name lookup.
-class OverloadedFunctionDecl : public NamedDecl {
-protected:
- OverloadedFunctionDecl(DeclContext *DC, DeclarationName N)
- : NamedDecl(OverloadedFunction, DC, SourceLocation(), N) { }
-
- /// Functions - the set of overloaded functions contained in this
- /// overload set.
- llvm::SmallVector<AnyFunctionDecl, 4> Functions;
-
- // FIXME: This should go away when we stop using
- // OverloadedFunctionDecl to store conversions in CXXRecordDecl.
- friend class CXXRecordDecl;
-
-public:
- typedef llvm::SmallVector<AnyFunctionDecl, 4>::iterator function_iterator;
- typedef llvm::SmallVector<AnyFunctionDecl, 4>::const_iterator
- function_const_iterator;
-
- static OverloadedFunctionDecl *Create(ASTContext &C, DeclContext *DC,
- DeclarationName N);
-
- /// \brief Add a new overloaded function or function template to the set
- /// of overloaded function templates.
- void addOverload(AnyFunctionDecl F);
-
- function_iterator function_begin() { return Functions.begin(); }
- function_iterator function_end() { return Functions.end(); }
- function_const_iterator function_begin() const { return Functions.begin(); }
- function_const_iterator function_end() const { return Functions.end(); }
-
- /// \brief Returns the number of overloaded functions stored in
- /// this set.
- unsigned size() const { return Functions.size(); }
-
- // Implement isa/cast/dyncast/etc.
- static bool classof(const Decl *D) {
- return D->getKind() == OverloadedFunction;
- }
- static bool classof(const OverloadedFunctionDecl *D) { return true; }
-};
-
-/// \brief Provides uniform iteration syntax for an overload set, function,
-/// or function template.
-class OverloadIterator {
- /// \brief An overloaded function set, function declaration, or
- /// function template declaration.
- NamedDecl *D;
-
- /// \brief If the declaration is an overloaded function set, this is the
- /// iterator pointing to the current position within that overloaded
- /// function set.
- OverloadedFunctionDecl::function_iterator Iter;
-
-public:
- typedef AnyFunctionDecl value_type;
- typedef value_type reference;
- typedef NamedDecl *pointer;
- typedef int difference_type;
- typedef std::forward_iterator_tag iterator_category;
-
- OverloadIterator() : D(0) { }
-
- OverloadIterator(FunctionDecl *FD) : D(FD) { }
- OverloadIterator(FunctionTemplateDecl *FTD)
- : D(reinterpret_cast<NamedDecl*>(FTD)) { }
- OverloadIterator(OverloadedFunctionDecl *Ovl)
- : D(Ovl), Iter(Ovl->function_begin()) { }
-
- OverloadIterator(NamedDecl *ND);
-
- reference operator*() const;
-
- pointer operator->() const { return (**this).get(); }
-
- OverloadIterator &operator++();
-
- OverloadIterator operator++(int) {
- OverloadIterator Temp(*this);
- ++(*this);
- return Temp;
- }
-
- bool Equals(const OverloadIterator &Other) const;
-};
-
-inline bool operator==(const OverloadIterator &X, const OverloadIterator &Y) {
- return X.Equals(Y);
-}
-
-inline bool operator!=(const OverloadIterator &X, const OverloadIterator &Y) {
- return !(X == Y);
-}
-
/// CXXBaseSpecifier - A base class of a C++ class.
///
/// Each CXXBaseSpecifier represents a single, direct base class (or
@@ -210,6 +108,7 @@ class CXXBaseSpecifier {
/// Range - The source code range that covers the full base
/// specifier, including the "virtual" (if present) and access
/// specifier (if present).
+ // FIXME: Move over to a TypeLoc!
SourceRange Range;
/// Virtual - Whether this is a virtual base class or not.
@@ -635,6 +534,10 @@ public:
/// [dcl.init.aggr]).
void setAggregate(bool Agg) { Aggregate = Agg; }
+ /// setMethodAsVirtual - Make input method virtual and set the necesssary
+ /// special function bits and other bits accordingly.
+ void setMethodAsVirtual(FunctionDecl *Method);
+
/// isPOD - Whether this class is a POD-type (C++ [class]p4), which is a class
/// 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
@@ -753,7 +656,7 @@ public:
/// \brief Determine whether this particular class is a specialization or
/// instantiation of a class template or member class of a class template,
/// and how it was instantiated or specialized.
- TemplateSpecializationKind getTemplateSpecializationKind();
+ TemplateSpecializationKind getTemplateSpecializationKind() const;
/// \brief Set the kind of specialization or template instantiation this is.
void setTemplateSpecializationKind(TemplateSpecializationKind TSK);
@@ -762,7 +665,7 @@ public:
CXXConstructorDecl *getDefaultConstructor(ASTContext &Context);
/// getDestructor - Returns the destructor decl for this class.
- const CXXDestructorDecl *getDestructor(ASTContext &Context);
+ CXXDestructorDecl *getDestructor(ASTContext &Context);
/// isLocalClass - If the class is a local class [class.local], returns
/// the enclosing function declaration.
@@ -802,6 +705,30 @@ public:
/// \todo add a separate paramaeter to configure IsDerivedFrom, rather than
/// tangling input and output in \p Paths
bool isDerivedFrom(CXXRecordDecl *Base, CXXBasePaths &Paths) const;
+
+ /// \brief Determine whether this class is provably not derived from
+ /// the type \p Base.
+ bool isProvablyNotDerivedFrom(const CXXRecordDecl *Base) const;
+
+ /// \brief Function type used by forallBases() as a callback.
+ ///
+ /// \param Base the definition of the base class
+ ///
+ /// \returns true if this base matched the search criteria
+ typedef bool ForallBasesCallback(const CXXRecordDecl *BaseDefinition,
+ void *UserData);
+
+ /// \brief Determines if the given callback holds for all the direct
+ /// or indirect base classes of this type.
+ ///
+ /// The class itself does not count as a base class. This routine
+ /// returns false if the class has non-computable base classes.
+ ///
+ /// \param AllowShortCircuit if false, forces the callback to be called
+ /// for every base class, even if a dependent or non-matching base was
+ /// found.
+ bool forallBases(ForallBasesCallback *BaseMatches, void *UserData,
+ bool AllowShortCircuit = true) const;
/// \brief Function type used by lookupInBases() to determine whether a
/// specific base class subobject matches the lookup criteria.
@@ -902,15 +829,15 @@ public:
class CXXMethodDecl : public FunctionDecl {
protected:
CXXMethodDecl(Kind DK, CXXRecordDecl *RD, SourceLocation L,
- DeclarationName N, QualType T, DeclaratorInfo *DInfo,
+ DeclarationName N, QualType T, TypeSourceInfo *TInfo,
bool isStatic, bool isInline)
- : FunctionDecl(DK, RD, L, N, T, DInfo, (isStatic ? Static : None),
+ : FunctionDecl(DK, RD, L, N, T, TInfo, (isStatic ? Static : None),
isInline) {}
public:
static CXXMethodDecl *Create(ASTContext &C, CXXRecordDecl *RD,
SourceLocation L, DeclarationName N,
- QualType T, DeclaratorInfo *DInfo,
+ QualType T, TypeSourceInfo *TInfo,
bool isStatic = false,
bool isInline = false);
@@ -968,6 +895,8 @@ public:
return getType()->getAs<FunctionProtoType>()->getTypeQuals();
}
+ bool hasInlineBody() const;
+
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) {
return D->getKind() >= CXXMethod && D->getKind() <= CXXConversion;
@@ -990,12 +919,13 @@ public:
/// };
/// @endcode
class CXXBaseOrMemberInitializer {
- /// BaseOrMember - This points to the entity being initialized,
- /// which is either a base class (a Type) or a non-static data
- /// member. When the low bit is 1, it's a base
- /// class; when the low bit is 0, it's a member.
- uintptr_t BaseOrMember;
-
+ /// \brief Either the base class name (stored as a TypeSourceInfo*) or the
+ /// field being initialized.
+ llvm::PointerUnion<TypeSourceInfo *, FieldDecl *> BaseOrMember;
+
+ /// \brief The source location for the field name.
+ SourceLocation MemberLocation;
+
/// Args - The arguments used to initialize the base or member.
Stmt **Args;
unsigned NumArgs;
@@ -1020,8 +950,8 @@ class CXXBaseOrMemberInitializer {
/// and AnonUnionMember holds field decl for au_i1.
llvm::PointerUnion<CXXConstructorDecl *, FieldDecl *> CtorOrAnonUnion;
- /// IdLoc - Location of the id in ctor-initializer list.
- SourceLocation IdLoc;
+ /// LParenLoc - Location of the left paren of the ctor-initializer.
+ SourceLocation LParenLoc;
/// RParenLoc - Location of the right paren of the ctor-initializer.
SourceLocation RParenLoc;
@@ -1029,18 +959,22 @@ class CXXBaseOrMemberInitializer {
public:
/// CXXBaseOrMemberInitializer - Creates a new base-class initializer.
explicit
- CXXBaseOrMemberInitializer(QualType BaseType, Expr **Args, unsigned NumArgs,
- CXXConstructorDecl *C,
- SourceLocation L, SourceLocation R);
+ CXXBaseOrMemberInitializer(ASTContext &Context,
+ TypeSourceInfo *TInfo, CXXConstructorDecl *C,
+ SourceLocation L,
+ Expr **Args, unsigned NumArgs,
+ SourceLocation R);
/// CXXBaseOrMemberInitializer - Creates a new member initializer.
explicit
- CXXBaseOrMemberInitializer(FieldDecl *Member, Expr **Args, unsigned NumArgs,
- CXXConstructorDecl *C,
- SourceLocation L, SourceLocation R);
+ CXXBaseOrMemberInitializer(ASTContext &Context,
+ FieldDecl *Member, SourceLocation MemberLoc,
+ CXXConstructorDecl *C, SourceLocation L,
+ Expr **Args, unsigned NumArgs,
+ SourceLocation R);
- /// ~CXXBaseOrMemberInitializer - Destroy the base or member initializer.
- ~CXXBaseOrMemberInitializer();
+ /// \brief Destroy the base or member initializer.
+ void Destroy(ASTContext &Context);
/// arg_iterator - Iterates through the member initialization
/// arguments.
@@ -1050,54 +984,54 @@ public:
/// arguments.
typedef ConstExprIterator const_arg_iterator;
- /// getBaseOrMember - get the generic 'member' representing either the field
- /// or a base class.
- void* getBaseOrMember() const { return reinterpret_cast<void*>(BaseOrMember); }
-
/// isBaseInitializer - Returns true when this initializer is
/// initializing a base class.
- bool isBaseInitializer() const { return (BaseOrMember & 0x1) != 0; }
+ bool isBaseInitializer() const { return BaseOrMember.is<TypeSourceInfo*>(); }
/// isMemberInitializer - Returns true when this initializer is
/// initializing a non-static data member.
- bool isMemberInitializer() const { return (BaseOrMember & 0x1) == 0; }
-
- /// getBaseClass - If this is a base class initializer, returns the
- /// type used to specify the initializer. The resulting type will be
- /// a class type or a typedef of a class type. If this is not a base
- /// class initializer, returns NULL.
- Type *getBaseClass() {
- if (isBaseInitializer())
- return reinterpret_cast<Type*>(BaseOrMember & ~0x01);
- else
- return 0;
- }
+ bool isMemberInitializer() const { return BaseOrMember.is<FieldDecl*>(); }
- /// getBaseClass - If this is a base class initializer, returns the
- /// type used to specify the initializer. The resulting type will be
- /// a class type or a typedef of a class type. If this is not a base
- /// class initializer, returns NULL.
- const Type *getBaseClass() const {
- if (isBaseInitializer())
- return reinterpret_cast<const Type*>(BaseOrMember & ~0x01);
- else
- return 0;
- }
+ /// If this is a base class initializer, returns the type of the
+ /// base class with location information. Otherwise, returns an NULL
+ /// type location.
+ TypeLoc getBaseClassLoc() const;
+ /// If this is a base class initializer, returns the type of the base class.
+ /// Otherwise, returns NULL.
+ const Type *getBaseClass() const;
+ Type *getBaseClass();
+
+ /// \brief Returns the declarator information for a base class initializer.
+ TypeSourceInfo *getBaseClassInfo() const {
+ return BaseOrMember.dyn_cast<TypeSourceInfo *>();
+ }
+
/// getMember - If this is a member initializer, returns the
/// declaration of the non-static data member being
/// initialized. Otherwise, returns NULL.
FieldDecl *getMember() {
if (isMemberInitializer())
- return reinterpret_cast<FieldDecl *>(BaseOrMember);
+ return BaseOrMember.get<FieldDecl*>();
else
return 0;
}
- void setMember(FieldDecl * anonUnionField) {
- BaseOrMember = reinterpret_cast<uintptr_t>(anonUnionField);
+ SourceLocation getMemberLocation() const {
+ return MemberLocation;
}
+ void setMember(FieldDecl *Member) {
+ assert(isMemberInitializer());
+ BaseOrMember = Member;
+ }
+
+ /// \brief Determine the source location of the initializer.
+ SourceLocation getSourceLocation() const;
+
+ /// \brief Determine the source range covering the entire initializer.
+ SourceRange getSourceRange() const;
+
FieldDecl *getAnonUnionMember() const {
return CtorOrAnonUnion.dyn_cast<FieldDecl *>();
}
@@ -1109,7 +1043,7 @@ public:
return CtorOrAnonUnion.dyn_cast<CXXConstructorDecl *>();
}
- SourceLocation getSourceLocation() const { return IdLoc; }
+ SourceLocation getLParenLoc() const { return LParenLoc; }
SourceLocation getRParenLoc() const { return RParenLoc; }
/// arg_begin() - Retrieve an iterator to the first initializer argument.
@@ -1155,9 +1089,9 @@ class CXXConstructorDecl : public CXXMethodDecl {
unsigned NumBaseOrMemberInitializers;
CXXConstructorDecl(CXXRecordDecl *RD, SourceLocation L,
- DeclarationName N, QualType T, DeclaratorInfo *DInfo,
+ DeclarationName N, QualType T, TypeSourceInfo *TInfo,
bool isExplicit, bool isInline, bool isImplicitlyDeclared)
- : CXXMethodDecl(CXXConstructor, RD, L, N, T, DInfo, false, isInline),
+ : CXXMethodDecl(CXXConstructor, RD, L, N, T, TInfo, false, isInline),
Explicit(isExplicit), ImplicitlyDefined(false),
BaseOrMemberInitializers(0), NumBaseOrMemberInitializers(0) {
setImplicit(isImplicitlyDeclared);
@@ -1167,7 +1101,7 @@ class CXXConstructorDecl : public CXXMethodDecl {
public:
static CXXConstructorDecl *Create(ASTContext &C, CXXRecordDecl *RD,
SourceLocation L, DeclarationName N,
- QualType T, DeclaratorInfo *DInfo,
+ QualType T, TypeSourceInfo *TInfo,
bool isExplicit,
bool isInline, bool isImplicitlyDeclared);
@@ -1294,7 +1228,7 @@ class CXXDestructorDecl : public CXXMethodDecl {
CXXDestructorDecl(CXXRecordDecl *RD, SourceLocation L,
DeclarationName N, QualType T,
bool isInline, bool isImplicitlyDeclared)
- : CXXMethodDecl(CXXDestructor, RD, L, N, T, /*DInfo=*/0, false, isInline),
+ : CXXMethodDecl(CXXDestructor, RD, L, N, T, /*TInfo=*/0, false, isInline),
ImplicitlyDefined(false), OperatorDelete(0) {
setImplicit(isImplicitlyDeclared);
}
@@ -1349,15 +1283,15 @@ class CXXConversionDecl : public CXXMethodDecl {
bool Explicit : 1;
CXXConversionDecl(CXXRecordDecl *RD, SourceLocation L,
- DeclarationName N, QualType T, DeclaratorInfo *DInfo,
+ DeclarationName N, QualType T, TypeSourceInfo *TInfo,
bool isInline, bool isExplicit)
- : CXXMethodDecl(CXXConversion, RD, L, N, T, DInfo, false, isInline),
+ : CXXMethodDecl(CXXConversion, RD, L, N, T, TInfo, false, isInline),
Explicit(isExplicit) { }
public:
static CXXConversionDecl *Create(ASTContext &C, CXXRecordDecl *RD,
SourceLocation L, DeclarationName N,
- QualType T, DeclaratorInfo *DInfo,
+ QualType T, TypeSourceInfo *TInfo,
bool isInline, bool isExplicit);
/// isExplicit - Whether this is an explicit conversion operator
diff --git a/include/clang/AST/DeclContextInternals.h b/include/clang/AST/DeclContextInternals.h
index c2b48cee36f4..32405ee81260 100644
--- a/include/clang/AST/DeclContextInternals.h
+++ b/include/clang/AST/DeclContextInternals.h
@@ -131,6 +131,25 @@ public:
return DK == DK_DeclID || DK == DK_ID_Vector;
}
+ void remove(NamedDecl *D) {
+ assert(!isNull() && "removing from empty list");
+ if (NamedDecl *Singleton = getAsDecl()) {
+ assert(Singleton == D && "list is different singleton");
+ (void)Singleton;
+ Data = 0;
+ return;
+ }
+
+ VectorTy &Vec = *getAsVector();
+ VectorTy::iterator I = std::find(Vec.begin(), Vec.end(),
+ reinterpret_cast<uintptr_t>(D));
+ assert(I != Vec.end() && "list does not contain decl");
+ Vec.erase(I);
+
+ assert(std::find(Vec.begin(), Vec.end(), reinterpret_cast<uintptr_t>(D))
+ == Vec.end() && "list still contains decl");
+ }
+
/// getLookupResult - Return an array of all the decls that this list
/// represents.
DeclContext::lookup_result getLookupResult(ASTContext &Context) {
@@ -200,11 +219,37 @@ public:
}
VectorTy &Vec = *getAsVector();
- if (isa<UsingDirectiveDecl>(D) ||
- D->getIdentifierNamespace() == Decl::IDNS_Tag)
+
+ // Using directives end up in a special entry which contains only
+ // other using directives, so all this logic is wasted for them.
+ // But avoiding the logic wastes time in the far-more-common case
+ // that we're *not* adding a new using directive.
+
+ // Tag declarations always go at the end of the list so that an
+ // iterator which points at the first tag will start a span of
+ // decls that only contains tags.
+ if (D->getIdentifierNamespace() == Decl::IDNS_Tag)
Vec.push_back(reinterpret_cast<uintptr_t>(D));
- else if (reinterpret_cast<NamedDecl *>(Vec.back())
- ->getIdentifierNamespace() == Decl::IDNS_Tag) {
+
+ // Resolved using declarations go at the front of the list so that
+ // they won't show up in other lookup results. Unresolved using
+ // declarations (which are always in IDNS_Using | IDNS_Ordinary)
+ // follow that so that the using declarations will be contiguous.
+ else if (D->getIdentifierNamespace() & Decl::IDNS_Using) {
+ VectorTy::iterator I = Vec.begin();
+ if (D->getIdentifierNamespace() != Decl::IDNS_Using) {
+ while (I != Vec.end() &&
+ reinterpret_cast<NamedDecl *>(*I)
+ ->getIdentifierNamespace() == Decl::IDNS_Using)
+ ++I;
+ }
+ Vec.insert(I, reinterpret_cast<uintptr_t>(D));
+
+ // All other declarations go at the end of the list, but before any
+ // tag declarations. But we can be clever about tag declarations
+ // because there can only ever be one in a scope.
+ } else if (reinterpret_cast<NamedDecl *>(Vec.back())
+ ->getIdentifierNamespace() == Decl::IDNS_Tag) {
uintptr_t TagD = Vec.back();
Vec.back() = reinterpret_cast<uintptr_t>(D);
Vec.push_back(TagD);
diff --git a/include/clang/AST/DeclNodes.def b/include/clang/AST/DeclNodes.def
index ec1b3b055cab..082299c41f50 100644
--- a/include/clang/AST/DeclNodes.def
+++ b/include/clang/AST/DeclNodes.def
@@ -75,7 +75,6 @@
DECL(TranslationUnit, Decl)
ABSTRACT_DECL(Named, Decl)
- DECL(OverloadedFunction, NamedDecl)
DECL(Namespace, NamedDecl)
DECL(UsingDirective, NamedDecl)
DECL(NamespaceAlias, NamedDecl)
@@ -143,7 +142,7 @@ DECL_CONTEXT_BASE(ObjCContainer)
LAST_DECL_CONTEXT(Block)
// Declaration ranges
-DECL_RANGE(Named, OverloadedFunction, ObjCCompatibleAlias)
+DECL_RANGE(Named, Namespace, ObjCCompatibleAlias)
DECL_RANGE(ObjCContainer, ObjCContainer, ObjCImplementation)
DECL_RANGE(Field, Field, ObjCAtDefsField)
DECL_RANGE(Type, Typedef, TemplateTypeParm)
diff --git a/include/clang/AST/DeclObjC.h b/include/clang/AST/DeclObjC.h
index 897776cdb9b8..fd8c3ef7fc55 100644
--- a/include/clang/AST/DeclObjC.h
+++ b/include/clang/AST/DeclObjC.h
@@ -578,14 +578,14 @@ public:
private:
ObjCIvarDecl(DeclContext *DC, SourceLocation L, IdentifierInfo *Id,
- QualType T, DeclaratorInfo *DInfo, AccessControl ac, Expr *BW)
- : FieldDecl(ObjCIvar, DC, L, Id, T, DInfo, BW, /*Mutable=*/false),
+ QualType T, TypeSourceInfo *TInfo, AccessControl ac, Expr *BW)
+ : FieldDecl(ObjCIvar, DC, L, Id, T, TInfo, BW, /*Mutable=*/false),
DeclAccess(ac) {}
public:
static ObjCIvarDecl *Create(ASTContext &C, DeclContext *DC, SourceLocation L,
IdentifierInfo *Id, QualType T,
- DeclaratorInfo *DInfo,
+ TypeSourceInfo *TInfo,
AccessControl ac, Expr *BW = NULL);
void setAccessControl(AccessControl ac) { DeclAccess = ac; }
@@ -612,7 +612,7 @@ private:
ObjCAtDefsFieldDecl(DeclContext *DC, SourceLocation L, IdentifierInfo *Id,
QualType T, Expr *BW)
: FieldDecl(ObjCAtDefsField, DC, L, Id, T,
- /*DInfo=*/0, // FIXME: Do ObjCAtDefs have declarators ?
+ /*TInfo=*/0, // FIXME: Do ObjCAtDefs have declarators ?
BW, /*Mutable=*/false) {}
public:
diff --git a/include/clang/AST/DeclTemplate.h b/include/clang/AST/DeclTemplate.h
index 3ecc4bb52b4c..d8b004a049ce 100644
--- a/include/clang/AST/DeclTemplate.h
+++ b/include/clang/AST/DeclTemplate.h
@@ -573,7 +573,7 @@ class TemplateTypeParmDecl : public TypeDecl {
bool ParameterPack : 1;
/// \brief The default template argument, if any.
- DeclaratorInfo *DefaultArgument;
+ TypeSourceInfo *DefaultArgument;
TemplateTypeParmDecl(DeclContext *DC, SourceLocation L, IdentifierInfo *Id,
bool Typename, QualType Type, bool ParameterPack)
@@ -601,7 +601,7 @@ public:
QualType getDefaultArgument() const { return DefaultArgument->getType(); }
/// \brief Retrieves the default argument's source information, if any.
- DeclaratorInfo *getDefaultArgumentInfo() const { return DefaultArgument; }
+ TypeSourceInfo *getDefaultArgumentInfo() const { return DefaultArgument; }
/// \brief Retrieves the location of the default argument declaration.
SourceLocation getDefaultArgumentLoc() const;
@@ -613,7 +613,7 @@ public:
/// \brief Set the default argument for this template parameter, and
/// whether that default argument was inherited from another
/// declaration.
- void setDefaultArgument(DeclaratorInfo *DefArg, bool Inherited) {
+ void setDefaultArgument(TypeSourceInfo *DefArg, bool Inherited) {
DefaultArgument = DefArg;
InheritedDefault = Inherited;
}
@@ -652,15 +652,15 @@ class NonTypeTemplateParmDecl
NonTypeTemplateParmDecl(DeclContext *DC, SourceLocation L, unsigned D,
unsigned P, IdentifierInfo *Id, QualType T,
- DeclaratorInfo *DInfo)
- : VarDecl(NonTypeTemplateParm, DC, L, Id, T, DInfo, VarDecl::None),
+ TypeSourceInfo *TInfo)
+ : VarDecl(NonTypeTemplateParm, DC, L, Id, T, TInfo, VarDecl::None),
TemplateParmPosition(D, P), DefaultArgument(0)
{ }
public:
static NonTypeTemplateParmDecl *
Create(ASTContext &C, DeclContext *DC, SourceLocation L, unsigned D,
- unsigned P, IdentifierInfo *Id, QualType T, DeclaratorInfo *DInfo);
+ unsigned P, IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo);
using TemplateParmPosition::getDepth;
using TemplateParmPosition::getPosition;
diff --git a/include/clang/AST/DeclarationName.h b/include/clang/AST/DeclarationName.h
index 676bd2ca7336..fcb4ae52e7eb 100644
--- a/include/clang/AST/DeclarationName.h
+++ b/include/clang/AST/DeclarationName.h
@@ -387,10 +387,11 @@ struct DenseMapInfo<clang::DeclarationName> {
isEqual(clang::DeclarationName LHS, clang::DeclarationName RHS) {
return LHS == RHS;
}
-
- static inline bool isPod() { return true; }
};
+template <>
+struct isPodLike<clang::DeclarationName> { static const bool value = true; };
+
} // end namespace llvm
#endif
diff --git a/include/clang/AST/Expr.h b/include/clang/AST/Expr.h
index 7cf9aabc6d6f..469598ff3723 100644
--- a/include/clang/AST/Expr.h
+++ b/include/clang/AST/Expr.h
@@ -309,6 +309,15 @@ public:
/// ParenExpr or CastExprs, returning their operand.
Expr *IgnoreParenNoopCasts(ASTContext &Ctx);
+ /// \brief Determine whether this expression is a default function argument.
+ ///
+ /// Default arguments are implicitly generated in the abstract syntax tree
+ /// by semantic analysis for function calls, object constructions, etc. in
+ /// C++. Default arguments are represented by \c CXXDefaultArgExpr nodes;
+ /// this routine also looks through any implicit casts to determine whether
+ /// the expression is a default argument.
+ bool isDefaultArgument() const;
+
const Expr* IgnoreParens() const {
return const_cast<Expr*>(this)->IgnoreParens();
}
@@ -389,7 +398,7 @@ class DeclRefExpr : public Expr {
// indicate whether (1) the declaration's name was explicitly qualified and
// (2) the declaration's name was followed by an explicit template
// argument list.
- llvm::PointerIntPair<NamedDecl *, 2> DecoratedD;
+ llvm::PointerIntPair<ValueDecl *, 2> DecoratedD;
// Loc - The location of the declaration name itself.
SourceLocation Loc;
@@ -427,7 +436,7 @@ class DeclRefExpr : public Expr {
}
DeclRefExpr(NestedNameSpecifier *Qualifier, SourceRange QualifierRange,
- NamedDecl *D, SourceLocation NameLoc,
+ ValueDecl *D, SourceLocation NameLoc,
const TemplateArgumentListInfo *TemplateArgs,
QualType T);
@@ -436,13 +445,13 @@ protected:
/// declaration reference expression.
void computeDependence();
- DeclRefExpr(StmtClass SC, NamedDecl *d, QualType t, SourceLocation l) :
+ DeclRefExpr(StmtClass SC, ValueDecl *d, QualType t, SourceLocation l) :
Expr(SC, t, false, false), DecoratedD(d, 0), Loc(l) {
computeDependence();
}
public:
- DeclRefExpr(NamedDecl *d, QualType t, SourceLocation l) :
+ DeclRefExpr(ValueDecl *d, QualType t, SourceLocation l) :
Expr(DeclRefExprClass, t, false, false), DecoratedD(d, 0), Loc(l) {
computeDependence();
}
@@ -454,14 +463,14 @@ public:
static DeclRefExpr *Create(ASTContext &Context,
NestedNameSpecifier *Qualifier,
SourceRange QualifierRange,
- NamedDecl *D,
+ ValueDecl *D,
SourceLocation NameLoc,
QualType T,
const TemplateArgumentListInfo *TemplateArgs = 0);
- NamedDecl *getDecl() { return DecoratedD.getPointer(); }
- const NamedDecl *getDecl() const { return DecoratedD.getPointer(); }
- void setDecl(NamedDecl *NewD) { DecoratedD.setPointer(NewD); }
+ ValueDecl *getDecl() { return DecoratedD.getPointer(); }
+ const ValueDecl *getDecl() const { return DecoratedD.getPointer(); }
+ void setDecl(ValueDecl *NewD) { DecoratedD.setPointer(NewD); }
SourceLocation getLocation() const { return Loc; }
void setLocation(SourceLocation L) { Loc = L; }
@@ -686,11 +695,6 @@ public:
SourceLocation getLocation() const { return Loc; }
void setLocation(SourceLocation L) { Loc = L; }
- // FIXME: The logic for computing the value of a predefined expr should go
- // into a method here that takes the inner-most code decl (a block, function
- // or objc method) that the expr lives in. This would allow sema and codegen
- // to be consistent for things like sizeof(__func__) etc.
-
virtual SourceRange getSourceRange() const { return SourceRange(Loc); }
static bool classof(const Stmt *T) {
@@ -975,7 +979,7 @@ class SizeOfAlignOfExpr : public Expr {
bool isSizeof : 1; // true if sizeof, false if alignof.
bool isType : 1; // true if operand is a type, false if an expression
union {
- DeclaratorInfo *Ty;
+ TypeSourceInfo *Ty;
Stmt *Ex;
} Argument;
SourceLocation OpLoc, RParenLoc;
@@ -984,15 +988,15 @@ protected:
virtual void DoDestroy(ASTContext& C);
public:
- SizeOfAlignOfExpr(bool issizeof, DeclaratorInfo *DInfo,
+ SizeOfAlignOfExpr(bool issizeof, TypeSourceInfo *TInfo,
QualType resultType, SourceLocation op,
SourceLocation rp) :
Expr(SizeOfAlignOfExprClass, resultType,
false, // Never type-dependent (C++ [temp.dep.expr]p3).
// Value-dependent if the argument is type-dependent.
- DInfo->getType()->isDependentType()),
+ TInfo->getType()->isDependentType()),
isSizeof(issizeof), isType(true), OpLoc(op), RParenLoc(rp) {
- Argument.Ty = DInfo;
+ Argument.Ty = TInfo;
}
SizeOfAlignOfExpr(bool issizeof, Expr *E,
@@ -1017,7 +1021,7 @@ public:
QualType getArgumentType() const {
return getArgumentTypeInfo()->getType();
}
- DeclaratorInfo *getArgumentTypeInfo() const {
+ TypeSourceInfo *getArgumentTypeInfo() const {
assert(isArgumentType() && "calling getArgumentType() when arg is expr");
return Argument.Ty;
}
@@ -1030,8 +1034,8 @@ public:
}
void setArgument(Expr *E) { Argument.Ex = E; isType = false; }
- void setArgument(DeclaratorInfo *DInfo) {
- Argument.Ty = DInfo;
+ void setArgument(TypeSourceInfo *TInfo) {
+ Argument.Ty = TInfo;
isType = true;
}
@@ -1252,7 +1256,7 @@ class MemberExpr : public Expr {
/// MemberDecl - This is the decl being referenced by the field/member name.
/// In X.F, this is the decl referenced by F.
- NamedDecl *MemberDecl;
+ ValueDecl *MemberDecl;
/// MemberLoc - This is the location of the member name.
SourceLocation MemberLoc;
@@ -1305,12 +1309,12 @@ class MemberExpr : public Expr {
}
MemberExpr(Expr *base, bool isarrow, NestedNameSpecifier *qual,
- SourceRange qualrange, NamedDecl *memberdecl, SourceLocation l,
+ SourceRange qualrange, ValueDecl *memberdecl, SourceLocation l,
const TemplateArgumentListInfo *targs, QualType ty);
public:
- MemberExpr(Expr *base, bool isarrow, NamedDecl *memberdecl, SourceLocation l,
- QualType ty)
+ MemberExpr(Expr *base, bool isarrow, ValueDecl *memberdecl,
+ SourceLocation l, QualType ty)
: Expr(MemberExprClass, ty,
base->isTypeDependent(), base->isValueDependent()),
Base(base), MemberDecl(memberdecl), MemberLoc(l), IsArrow(isarrow),
@@ -1323,7 +1327,7 @@ public:
static MemberExpr *Create(ASTContext &C, Expr *base, bool isarrow,
NestedNameSpecifier *qual, SourceRange qualrange,
- NamedDecl *memberdecl,
+ ValueDecl *memberdecl,
SourceLocation l,
const TemplateArgumentListInfo *targs,
QualType ty);
@@ -1335,8 +1339,8 @@ public:
///
/// The returned declaration will either be a FieldDecl or (in C++)
/// a CXXMethodDecl.
- NamedDecl *getMemberDecl() const { return MemberDecl; }
- void setMemberDecl(NamedDecl *D) { MemberDecl = D; }
+ ValueDecl *getMemberDecl() const { return MemberDecl; }
+ void setMemberDecl(ValueDecl *D) { MemberDecl = D; }
/// \brief Determines whether this member expression actually had
/// a C++ nested-name-specifier prior to the name of the member, e.g.,
@@ -1576,7 +1580,14 @@ public:
CK_FloatingCast,
/// CK_MemberPointerToBoolean - Member pointer to boolean
- CK_MemberPointerToBoolean
+ CK_MemberPointerToBoolean,
+
+ /// CK_AnyPointerToObjCPointerCast - Casting any pointer to objective-c
+ /// pointer
+ CK_AnyPointerToObjCPointerCast,
+ /// CK_AnyPointerToBlockPointerCast - Casting any pointer to block
+ /// pointer
+ CK_AnyPointerToBlockPointerCast
};
@@ -1607,6 +1618,14 @@ public:
const Expr *getSubExpr() const { return cast<Expr>(Op); }
void setSubExpr(Expr *E) { Op = E; }
+ /// \brief Retrieve the cast subexpression as it was written in the source
+ /// code, looking through any implicit casts or other intermediate nodes
+ /// introduced by semantic analysis.
+ Expr *getSubExprAsWritten();
+ const Expr *getSubExprAsWritten() const {
+ return const_cast<CastExpr *>(this)->getSubExprAsWritten();
+ }
+
static bool classof(const Stmt *T) {
StmtClass SC = T->getStmtClass();
if (SC >= CXXNamedCastExprClass && SC <= CXXFunctionalCastExprClass)
diff --git a/include/clang/AST/ExprCXX.h b/include/clang/AST/ExprCXX.h
index 23844ce5d967..00ea202abde7 100644
--- a/include/clang/AST/ExprCXX.h
+++ b/include/clang/AST/ExprCXX.h
@@ -527,6 +527,7 @@ public:
const_arg_iterator arg_begin() const { return Args; }
const_arg_iterator arg_end() const { return Args + NumArgs; }
+ Expr **getArgs() const { return reinterpret_cast<Expr **>(Args); }
unsigned getNumArgs() const { return NumArgs; }
/// getArg - Return the specified argument.
@@ -1410,18 +1411,26 @@ public:
/// \brief Represents a C++ member access expression where the actual
/// member referenced could not be resolved because the base
/// expression or the member name was dependent.
+///
+/// Like UnresolvedMemberExprs, these can be either implicit or
+/// explicit accesses. It is only possible to get one of these with
+/// an implicit access if a qualifier is provided.
class CXXDependentScopeMemberExpr : public Expr {
/// \brief The expression for the base pointer or class reference,
- /// e.g., the \c x in x.f.
+ /// e.g., the \c x in x.f. Can be null in implicit accesses.
Stmt *Base;
+ /// \brief The type of the base expression. Never null, even for
+ /// implicit accesses.
+ QualType BaseType;
+
/// \brief Whether this member expression used the '->' operator or
/// the '.' operator.
bool IsArrow : 1;
/// \brief Whether this member expression has explicitly-specified template
/// arguments.
- bool HasExplicitTemplateArgumentList : 1;
+ bool HasExplicitTemplateArgs : 1;
/// \brief The location of the '->' or '.' operator.
SourceLocation OperatorLoc;
@@ -1452,9 +1461,7 @@ class CXXDependentScopeMemberExpr : public Expr {
/// \brief Retrieve the explicit template argument list that followed the
/// member template name, if any.
ExplicitTemplateArgumentList *getExplicitTemplateArgumentList() {
- if (!HasExplicitTemplateArgumentList)
- return 0;
-
+ assert(HasExplicitTemplateArgs);
return reinterpret_cast<ExplicitTemplateArgumentList *>(this + 1);
}
@@ -1466,7 +1473,7 @@ class CXXDependentScopeMemberExpr : public Expr {
}
CXXDependentScopeMemberExpr(ASTContext &C,
- Expr *Base, bool IsArrow,
+ Expr *Base, QualType BaseType, bool IsArrow,
SourceLocation OperatorLoc,
NestedNameSpecifier *Qualifier,
SourceRange QualifierRange,
@@ -1477,7 +1484,8 @@ class CXXDependentScopeMemberExpr : public Expr {
public:
CXXDependentScopeMemberExpr(ASTContext &C,
- Expr *Base, bool IsArrow,
+ Expr *Base, QualType BaseType,
+ bool IsArrow,
SourceLocation OperatorLoc,
NestedNameSpecifier *Qualifier,
SourceRange QualifierRange,
@@ -1485,15 +1493,15 @@ public:
DeclarationName Member,
SourceLocation MemberLoc)
: Expr(CXXDependentScopeMemberExprClass, C.DependentTy, true, true),
- Base(Base), IsArrow(IsArrow), HasExplicitTemplateArgumentList(false),
- OperatorLoc(OperatorLoc),
+ Base(Base), BaseType(BaseType), IsArrow(IsArrow),
+ HasExplicitTemplateArgs(false), OperatorLoc(OperatorLoc),
Qualifier(Qualifier), QualifierRange(QualifierRange),
FirstQualifierFoundInScope(FirstQualifierFoundInScope),
Member(Member), MemberLoc(MemberLoc) { }
static CXXDependentScopeMemberExpr *
Create(ASTContext &C,
- Expr *Base, bool IsArrow,
+ Expr *Base, QualType BaseType, bool IsArrow,
SourceLocation OperatorLoc,
NestedNameSpecifier *Qualifier,
SourceRange QualifierRange,
@@ -1502,11 +1510,21 @@ public:
SourceLocation MemberLoc,
const TemplateArgumentListInfo *TemplateArgs);
+ /// \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.
+ bool isImplicitAccess() const { return Base == 0; }
+
/// \brief Retrieve the base object of this member expressions,
/// e.g., the \c x in \c x.m.
- Expr *getBase() { return cast<Expr>(Base); }
+ Expr *getBase() const {
+ assert(!isImplicitAccess());
+ return cast<Expr>(Base);
+ }
void setBase(Expr *E) { Base = E; }
+ QualType getBaseType() const { return BaseType; }
+
/// \brief Determine whether this member expression used the '->'
/// operator; otherwise, it used the '.' operator.
bool isArrow() const { return IsArrow; }
@@ -1551,60 +1569,59 @@ public:
/// \brief Determines whether this member expression actually had a C++
/// template argument list explicitly specified, e.g., x.f<int>.
- bool hasExplicitTemplateArgumentList() const {
- return HasExplicitTemplateArgumentList;
+ bool hasExplicitTemplateArgs() const {
+ return HasExplicitTemplateArgs;
}
/// \brief Copies the template arguments (if present) into the given
/// structure.
void copyTemplateArgumentsInto(TemplateArgumentListInfo &List) const {
- if (hasExplicitTemplateArgumentList())
- getExplicitTemplateArgumentList()->copyInto(List);
+ assert(HasExplicitTemplateArgs);
+ getExplicitTemplateArgumentList()->copyInto(List);
}
/// \brief Retrieve the location of the left angle bracket following the
/// member name ('<'), if any.
SourceLocation getLAngleLoc() const {
- if (!HasExplicitTemplateArgumentList)
- return SourceLocation();
-
+ assert(HasExplicitTemplateArgs);
return getExplicitTemplateArgumentList()->LAngleLoc;
}
/// \brief Retrieve the template arguments provided as part of this
/// template-id.
const TemplateArgumentLoc *getTemplateArgs() const {
- if (!HasExplicitTemplateArgumentList)
- return 0;
-
+ assert(HasExplicitTemplateArgs);
return getExplicitTemplateArgumentList()->getTemplateArgs();
}
/// \brief Retrieve the number of template arguments provided as part of this
/// template-id.
unsigned getNumTemplateArgs() const {
- if (!HasExplicitTemplateArgumentList)
- return 0;
-
+ assert(HasExplicitTemplateArgs);
return getExplicitTemplateArgumentList()->NumTemplateArgs;
}
/// \brief Retrieve the location of the right angle bracket following the
/// template arguments ('>').
SourceLocation getRAngleLoc() const {
- if (!HasExplicitTemplateArgumentList)
- return SourceLocation();
-
+ assert(HasExplicitTemplateArgs);
return getExplicitTemplateArgumentList()->RAngleLoc;
}
virtual SourceRange getSourceRange() const {
- if (HasExplicitTemplateArgumentList)
- return SourceRange(Base->getSourceRange().getBegin(),
- getRAngleLoc());
+ SourceRange Range;
+ if (!isImplicitAccess())
+ Range.setBegin(Base->getSourceRange().getBegin());
+ else if (getQualifier())
+ Range.setBegin(getQualifierRange().getBegin());
+ else
+ Range.setBegin(MemberLoc);
- return SourceRange(Base->getSourceRange().getBegin(),
- MemberLoc);
+ if (hasExplicitTemplateArgs())
+ Range.setEnd(getRAngleLoc());
+ else
+ Range.setEnd(MemberLoc);
+ return Range;
}
static bool classof(const Stmt *T) {
@@ -1618,17 +1635,31 @@ public:
};
/// \brief Represents a C++ member access expression for which lookup
-/// produced a set of overloaded functions. These are replaced with
-/// MemberExprs in the final AST.
+/// produced a set of overloaded functions.
+///
+/// The member access may be explicit or implicit:
+/// struct A {
+/// int a, b;
+/// int explicitAccess() { return this->a + this->A::b; }
+/// int implicitAccess() { return a + A::b; }
+/// };
+///
+/// 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 Results;
/// \brief The expression for the base pointer or class reference,
- /// e.g., the \c x in x.f.
+ /// 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 Whether this member expression used the '->' operator or
/// the '.' operator.
bool IsArrow : 1;
@@ -1672,7 +1703,7 @@ class UnresolvedMemberExpr : public Expr {
UnresolvedMemberExpr(QualType T, bool Dependent,
bool HasUnresolvedUsing,
- Expr *Base, bool IsArrow,
+ Expr *Base, QualType BaseType, bool IsArrow,
SourceLocation OperatorLoc,
NestedNameSpecifier *Qualifier,
SourceRange QualifierRange,
@@ -1683,7 +1714,7 @@ class UnresolvedMemberExpr : public Expr {
public:
static UnresolvedMemberExpr *
Create(ASTContext &C, bool Dependent, bool HasUnresolvedUsing,
- Expr *Base, bool IsArrow,
+ Expr *Base, QualType BaseType, bool IsArrow,
SourceLocation OperatorLoc,
NestedNameSpecifier *Qualifier,
SourceRange QualifierRange,
@@ -1704,11 +1735,21 @@ public:
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.
+ bool isImplicitAccess() const { return Base == 0; }
+
/// \brief Retrieve the base object of this member expressions,
/// e.g., the \c x in \c x.m.
- Expr *getBase() { return cast<Expr>(Base); }
+ Expr *getBase() {
+ assert(!isImplicitAccess());
+ return cast<Expr>(Base);
+ }
void setBase(Expr *E) { Base = E; }
+ QualType getBaseType() const { return BaseType; }
+
/// \brief Determine whether this member expression used the '->'
/// operator; otherwise, it used the '.' operator.
bool isArrow() const { return IsArrow; }
@@ -1772,7 +1813,14 @@ public:
}
virtual SourceRange getSourceRange() const {
- SourceRange Range = Base->getSourceRange();
+ SourceRange Range;
+ if (!isImplicitAccess())
+ Range.setBegin(Base->getSourceRange().getBegin());
+ else if (getQualifier())
+ Range.setBegin(getQualifierRange().getBegin());
+ else
+ Range.setBegin(MemberLoc);
+
if (hasExplicitTemplateArgs())
Range.setEnd(getRAngleLoc());
else
diff --git a/include/clang/AST/RecordLayout.h b/include/clang/AST/RecordLayout.h
index 5d2973ea9dab..a8334b694080 100644
--- a/include/clang/AST/RecordLayout.h
+++ b/include/clang/AST/RecordLayout.h
@@ -119,13 +119,6 @@ private:
/// VBaseOffsets - Contains a map from vbase classes to their offset.
/// FIXME: This should really use a SmallPtrMap, once we have one in LLVM :)
llvm::DenseMap<const CXXRecordDecl *, uint64_t> VBaseOffsets;
-
- /// KeyFunction - The key function, according to the Itanium C++ ABI,
- /// section 5.2.3:
- ///
- /// ...the first non-pure virtual function that is not inline at the point
- /// of class definition.
- const CXXMethodDecl *KeyFunction;
};
/// CXXInfo - If the record layout is for a C++ record, this will have
@@ -154,8 +147,7 @@ private:
const std::pair<const CXXRecordDecl *, uint64_t> *bases,
unsigned numbases,
const std::pair<const CXXRecordDecl *, uint64_t> *vbases,
- unsigned numvbases,
- const CXXMethodDecl *KeyFunction)
+ unsigned numvbases)
: Size(size), DataSize(datasize), FieldOffsets(0), Alignment(alignment),
FieldCount(fieldcount), CXXInfo(new CXXRecordLayoutInfo) {
if (FieldCount > 0) {
@@ -171,7 +163,6 @@ private:
CXXInfo->BaseOffsets[bases[i].first] = bases[i].second;
for (unsigned i = 0; i != numvbases; ++i)
CXXInfo->VBaseOffsets[vbases[i].first] = vbases[i].second;
- CXXInfo->KeyFunction = KeyFunction;
}
~ASTRecordLayout() {
@@ -254,13 +245,6 @@ public:
return CXXInfo->VBaseOffsets[VBase];
}
- /// getKeyFunction - Get the key function.
- const CXXMethodDecl *getKeyFunction() const {
- assert(CXXInfo && "Record layout does not have C++ specific info!");
-
- return CXXInfo->KeyFunction;
- }
-
primary_base_info_iterator primary_base_begin() const {
assert(CXXInfo && "Record layout does not have C++ specific info!");
diff --git a/include/clang/AST/StmtCXX.h b/include/clang/AST/StmtCXX.h
index 64eea2429c5d..09ea4ca2101b 100644
--- a/include/clang/AST/StmtCXX.h
+++ b/include/clang/AST/StmtCXX.h
@@ -68,10 +68,11 @@ public:
Stmt **handlers, unsigned numHandlers);
virtual SourceRange getSourceRange() const {
- return SourceRange(TryLoc, Stmts.back()->getLocEnd());
+ return SourceRange(getTryLoc(), getEndLoc());
}
SourceLocation getTryLoc() const { return TryLoc; }
+ SourceLocation getEndLoc() const { return Stmts.back()->getLocEnd(); }
CompoundStmt *getTryBlock() { return llvm::cast<CompoundStmt>(Stmts[0]); }
const CompoundStmt *getTryBlock() const {
diff --git a/include/clang/AST/TemplateBase.h b/include/clang/AST/TemplateBase.h
index b46b3dc5d2d2..fe037992ad2f 100644
--- a/include/clang/AST/TemplateBase.h
+++ b/include/clang/AST/TemplateBase.h
@@ -29,7 +29,7 @@ namespace clang {
class Decl;
class Expr;
-class DeclaratorInfo;
+class TypeSourceInfo;
/// \brief Represents a template argument within a class template
/// specialization.
@@ -267,7 +267,7 @@ struct TemplateArgumentLocInfo {
private:
union {
Expr *Expression;
- DeclaratorInfo *Declarator;
+ TypeSourceInfo *Declarator;
struct {
unsigned QualifierRange[2];
unsigned TemplateNameLoc;
@@ -277,7 +277,7 @@ private:
#ifndef NDEBUG
enum Kind {
K_None,
- K_DeclaratorInfo,
+ K_TypeSourceInfo,
K_Expression,
K_Template
} Kind;
@@ -291,10 +291,10 @@ public:
#endif
{}
- TemplateArgumentLocInfo(DeclaratorInfo *DInfo)
- : Declarator(DInfo)
+ TemplateArgumentLocInfo(TypeSourceInfo *TInfo)
+ : Declarator(TInfo)
#ifndef NDEBUG
- , Kind(K_DeclaratorInfo)
+ , Kind(K_TypeSourceInfo)
#endif
{}
@@ -316,8 +316,8 @@ public:
Template.TemplateNameLoc = TemplateNameLoc.getRawEncoding();
}
- DeclaratorInfo *getAsDeclaratorInfo() const {
- assert(Kind == K_DeclaratorInfo);
+ TypeSourceInfo *getAsTypeSourceInfo() const {
+ assert(Kind == K_TypeSourceInfo);
return Declarator;
}
@@ -342,7 +342,7 @@ public:
void validateForArgument(const TemplateArgument &Arg) {
switch (Arg.getKind()) {
case TemplateArgument::Type:
- assert(Kind == K_DeclaratorInfo);
+ assert(Kind == K_TypeSourceInfo);
break;
case TemplateArgument::Expression:
case TemplateArgument::Declaration:
@@ -356,7 +356,7 @@ public:
assert(Kind == K_None);
break;
case TemplateArgument::Null:
- llvm::llvm_unreachable("source info for null template argument?");
+ llvm_unreachable("source info for null template argument?");
}
}
#endif
@@ -376,8 +376,8 @@ public:
: Argument(Argument), LocInfo(Opaque) {
}
- TemplateArgumentLoc(const TemplateArgument &Argument, DeclaratorInfo *DInfo)
- : Argument(Argument), LocInfo(DInfo) {
+ TemplateArgumentLoc(const TemplateArgument &Argument, TypeSourceInfo *TInfo)
+ : Argument(Argument), LocInfo(TInfo) {
assert(Argument.getKind() == TemplateArgument::Type);
}
@@ -412,9 +412,9 @@ public:
return LocInfo;
}
- DeclaratorInfo *getSourceDeclaratorInfo() const {
+ TypeSourceInfo *getTypeSourceInfo() const {
assert(Argument.getKind() == TemplateArgument::Type);
- return LocInfo.getAsDeclaratorInfo();
+ return LocInfo.getAsTypeSourceInfo();
}
Expr *getSourceExpression() const {
diff --git a/include/clang/AST/TemplateName.h b/include/clang/AST/TemplateName.h
index 8ef8fb51416c..aafe96381192 100644
--- a/include/clang/AST/TemplateName.h
+++ b/include/clang/AST/TemplateName.h
@@ -31,7 +31,34 @@ struct PrintingPolicy;
class QualifiedTemplateName;
class NamedDecl;
class TemplateDecl;
-class OverloadedFunctionDecl;
+
+/// \brief A structure for storing the information associated with an
+/// overloaded template name.
+class OverloadedTemplateStorage {
+ union {
+ unsigned Size;
+ NamedDecl *Storage[1];
+ };
+
+ friend class ASTContext;
+
+ OverloadedTemplateStorage(unsigned Size) : Size(Size) {}
+
+ NamedDecl **getStorage() {
+ return &Storage[1];
+ }
+ NamedDecl * const *getStorage() const {
+ return &Storage[1];
+ }
+
+public:
+ typedef NamedDecl *const *iterator;
+
+ unsigned size() const { return Size; }
+
+ iterator begin() const { return getStorage(); }
+ iterator end() const { return getStorage() + size(); }
+};
/// \brief Represents a C++ template name within the type system.
///
@@ -61,7 +88,8 @@ class OverloadedFunctionDecl;
/// specifier in the typedef. "apply" is a nested template, and can
/// only be understood in the context of
class TemplateName {
- typedef llvm::PointerUnion4<TemplateDecl *, OverloadedFunctionDecl *,
+ typedef llvm::PointerUnion4<TemplateDecl *,
+ OverloadedTemplateStorage *,
QualifiedTemplateName *,
DependentTemplateName *> StorageType;
@@ -74,8 +102,8 @@ class TemplateName {
public:
TemplateName() : Storage() { }
explicit TemplateName(TemplateDecl *Template) : Storage(Template) { }
- explicit TemplateName(OverloadedFunctionDecl *FunctionTemplates)
- : Storage(FunctionTemplates) { }
+ explicit TemplateName(OverloadedTemplateStorage *Storage)
+ : Storage(Storage) { }
explicit TemplateName(QualifiedTemplateName *Qual) : Storage(Qual) { }
explicit TemplateName(DependentTemplateName *Dep) : Storage(Dep) { }
@@ -98,7 +126,9 @@ public:
/// name refers to, if known. If the template name does not refer to a
/// specific set of function templates because it is a dependent name or
/// refers to a single template, returns NULL.
- OverloadedFunctionDecl *getAsOverloadedFunctionDecl() const;
+ OverloadedTemplateStorage *getAsOverloadedTemplate() const {
+ return Storage.dyn_cast<OverloadedTemplateStorage *>();
+ }
/// \brief Retrieve the underlying qualified template name
/// structure, if any.
@@ -166,19 +196,14 @@ class QualifiedTemplateName : public llvm::FoldingSetNode {
/// \brief The template declaration or set of overloaded function templates
/// that this qualified name refers to.
- NamedDecl *Template;
+ TemplateDecl *Template;
friend class ASTContext;
QualifiedTemplateName(NestedNameSpecifier *NNS, bool TemplateKeyword,
TemplateDecl *Template)
: Qualifier(NNS, TemplateKeyword? 1 : 0),
- Template(reinterpret_cast<NamedDecl *>(Template)) { }
-
- QualifiedTemplateName(NestedNameSpecifier *NNS, bool TemplateKeyword,
- OverloadedFunctionDecl *Template)
- : Qualifier(NNS, TemplateKeyword? 1 : 0),
- Template(reinterpret_cast<NamedDecl *>(Template)) { }
+ Template(Template) { }
public:
/// \brief Return the nested name specifier that qualifies this name.
@@ -188,26 +213,20 @@ public:
/// keyword.
bool hasTemplateKeyword() const { return Qualifier.getInt(); }
- /// \brief The template declaration or set of overloaded functions that
- /// that qualified name refers to.
- NamedDecl *getDecl() const { return Template; }
+ /// \brief The template declaration that this qualified name refers
+ /// to.
+ TemplateDecl *getDecl() const { return Template; }
/// \brief The template declaration to which this qualified name
- /// refers, or NULL if this qualified name refers to a set of overloaded
- /// function templates.
- TemplateDecl *getTemplateDecl() const;
-
- /// \brief The set of overloaded function tempaltes to which this qualified
- /// name refers, or NULL if this qualified name refers to a single
- /// template declaration.
- OverloadedFunctionDecl *getOverloadedFunctionDecl() const;
+ /// refers.
+ TemplateDecl *getTemplateDecl() const { return Template; }
void Profile(llvm::FoldingSetNodeID &ID) {
- Profile(ID, getQualifier(), hasTemplateKeyword(), getDecl());
+ Profile(ID, getQualifier(), hasTemplateKeyword(), getTemplateDecl());
}
static void Profile(llvm::FoldingSetNodeID &ID, NestedNameSpecifier *NNS,
- bool TemplateKeyword, NamedDecl *Template) {
+ bool TemplateKeyword, TemplateDecl *Template) {
ID.AddPointer(NNS);
ID.AddBoolean(TemplateKeyword);
ID.AddPointer(Template);
diff --git a/include/clang/AST/Type.h b/include/clang/AST/Type.h
index 349487f8794b..d22a646ece5b 100644
--- a/include/clang/AST/Type.h
+++ b/include/clang/AST/Type.h
@@ -35,7 +35,9 @@ namespace clang {
TypeAlignmentInBits = 3,
TypeAlignment = 1 << TypeAlignmentInBits
};
- class Type; class ExtQuals;
+ class Type;
+ class ExtQuals;
+ class QualType;
}
namespace llvm {
@@ -59,6 +61,9 @@ namespace llvm {
}
enum { NumLowBitsAvailable = clang::TypeAlignmentInBits };
};
+
+ template <>
+ struct isPodLike<clang::QualType> { static const bool value = true; };
}
namespace clang {
@@ -76,6 +81,7 @@ namespace clang {
class ObjCInterfaceDecl;
class ObjCProtocolDecl;
class ObjCMethodDecl;
+ class UnresolvedUsingTypenameDecl;
class Expr;
class Stmt;
class SourceLocation;
@@ -791,6 +797,10 @@ public:
/// isPODType - Return true if this is a plain-old-data type (C++ 3.9p10).
bool isPODType() const;
+ /// isLiteralType - Return true if this is a literal type
+ /// (C++0x [basic.types]p10)
+ bool isLiteralType() const;
+
/// isVariablyModifiedType (C99 6.7.5.2p2) - Return true for variable array
/// types that have a non-constant expression. This does not include "[]".
bool isVariablyModifiedType() const;
@@ -808,8 +818,9 @@ public:
bool isBooleanType() const;
bool isCharType() const;
bool isWideCharType() const;
+ bool isAnyCharacterType() const;
bool isIntegralType() const;
-
+
/// Floating point categories.
bool isRealFloatingType() const; // C99 6.2.5p10 (float, double, long double)
/// isComplexType() does *not* include complex integers (a GCC extension).
@@ -1859,6 +1870,38 @@ public:
};
+/// \brief Represents the dependent type named by a dependently-scoped
+/// typename using declaration, e.g.
+/// using typename Base<T>::foo;
+/// Template instantiation turns these into the underlying type.
+class UnresolvedUsingType : public Type {
+ UnresolvedUsingTypenameDecl *Decl;
+
+ UnresolvedUsingType(UnresolvedUsingTypenameDecl *D)
+ : Type(UnresolvedUsing, QualType(), true), Decl(D) {}
+ friend class ASTContext; // ASTContext creates these.
+public:
+
+ UnresolvedUsingTypenameDecl *getDecl() const { return Decl; }
+
+ bool isSugared() const { return false; }
+ QualType desugar() const { return QualType(this, 0); }
+
+ static bool classof(const Type *T) {
+ return T->getTypeClass() == UnresolvedUsing;
+ }
+ static bool classof(const UnresolvedUsingType *) { return true; }
+
+ void Profile(llvm::FoldingSetNodeID &ID) {
+ return Profile(ID, Decl);
+ }
+ static void Profile(llvm::FoldingSetNodeID &ID,
+ UnresolvedUsingTypenameDecl *D) {
+ ID.AddPointer(D);
+ }
+};
+
+
class TypedefType : public Type {
TypedefDecl *Decl;
protected:
diff --git a/include/clang/AST/TypeLoc.h b/include/clang/AST/TypeLoc.h
index f08ca6bf469b..a9b7f7e94337 100644
--- a/include/clang/AST/TypeLoc.h
+++ b/include/clang/AST/TypeLoc.h
@@ -19,7 +19,7 @@
namespace clang {
class ParmVarDecl;
- class DeclaratorInfo;
+ class TypeSourceInfo;
class UnqualTypeLoc;
// Predeclare all the type nodes.
@@ -340,16 +340,20 @@ public:
}
};
+
struct TypeSpecLocInfo {
SourceLocation NameLoc;
};
/// \brief A reasonable base class for TypeLocs that correspond to
/// types that are written as a type-specifier.
-template <class Derived, class TypeClass, class LocalData = TypeSpecLocInfo>
-class TypeSpecTypeLoc
- : public ConcreteTypeLoc<UnqualTypeLoc, Derived, TypeClass, LocalData> {
+class TypeSpecTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
+ TypeSpecTypeLoc,
+ Type,
+ TypeSpecLocInfo> {
public:
+ enum { LocalDataSize = sizeof(TypeSpecLocInfo) };
+
SourceLocation getNameLoc() const {
return this->getLocalData()->NameLoc;
}
@@ -362,31 +366,79 @@ public:
void initializeLocal(SourceLocation Loc) {
setNameLoc(Loc);
}
+
+ static bool classof(const TypeLoc *TL);
+ static bool classof(const TypeSpecTypeLoc *TL) { return true; }
};
+
/// \brief Wrapper for source info for typedefs.
-class TypedefTypeLoc : public TypeSpecTypeLoc<TypedefTypeLoc,TypedefType> {
+class TypedefTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
+ TypedefTypeLoc,
+ TypedefType> {
public:
TypedefDecl *getTypedefDecl() const {
return getTypePtr()->getDecl();
}
};
+/// \brief Wrapper for source info for unresolved typename using decls.
+class UnresolvedUsingTypeLoc :
+ public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
+ UnresolvedUsingTypeLoc,
+ UnresolvedUsingType> {
+public:
+ UnresolvedUsingTypenameDecl *getDecl() const {
+ return getTypePtr()->getDecl();
+ }
+};
+
+/// \brief Wrapper for source info for tag types. Note that this only
+/// records source info for the name itself; a type written 'struct foo'
+/// should be represented as an ElaboratedTypeLoc. We currently
+/// only do that when C++ is enabled because of the expense of
+/// creating an ElaboratedType node for so many type references in C.
+class TagTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
+ TagTypeLoc,
+ TagType> {
+public:
+ TagDecl *getDecl() const { return getTypePtr()->getDecl(); }
+};
+
+/// \brief Wrapper for source info for record types.
+class RecordTypeLoc : public InheritingConcreteTypeLoc<TagTypeLoc,
+ RecordTypeLoc,
+ RecordType> {
+public:
+ RecordDecl *getDecl() const { return getTypePtr()->getDecl(); }
+};
+
+/// \brief Wrapper for source info for enum types.
+class EnumTypeLoc : public InheritingConcreteTypeLoc<TagTypeLoc,
+ EnumTypeLoc,
+ EnumType> {
+public:
+ EnumDecl *getDecl() const { return getTypePtr()->getDecl(); }
+};
/// \brief Wrapper for source info for builtin types.
-class BuiltinTypeLoc : public TypeSpecTypeLoc<BuiltinTypeLoc,
- BuiltinType> {
+class BuiltinTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
+ BuiltinTypeLoc,
+ BuiltinType> {
};
/// \brief Wrapper for template type parameters.
-class TemplateTypeParmTypeLoc : public TypeSpecTypeLoc<TemplateTypeParmTypeLoc,
- TemplateTypeParmType> {
+class TemplateTypeParmTypeLoc :
+ public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
+ TemplateTypeParmTypeLoc,
+ TemplateTypeParmType> {
};
/// \brief Wrapper for substituted template type parameters.
class SubstTemplateTypeParmTypeLoc :
- public TypeSpecTypeLoc<SubstTemplateTypeParmTypeLoc,
- SubstTemplateTypeParmType> {
+ public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
+ SubstTemplateTypeParmTypeLoc,
+ SubstTemplateTypeParmType> {
};
@@ -889,7 +941,7 @@ public:
assert(size == Loc.getFullDataSize());
// We're potentially copying Expr references here. We don't
- // bother retaining them because DeclaratorInfos live forever, so
+ // bother retaining them because TypeSourceInfos live forever, so
// as long as the Expr was retained when originally written into
// the TypeLoc, we're okay.
memcpy(Data, Loc.Data, size);
@@ -916,7 +968,7 @@ public:
break;
case TemplateArgument::Type:
- Info = TemplateArgumentLocInfo((DeclaratorInfo*) 0);
+ Info = TemplateArgumentLocInfo((TypeSourceInfo*) 0);
break;
case TemplateArgument::Template:
@@ -944,63 +996,84 @@ private:
}
};
-// None of these types have proper implementations yet.
+//===----------------------------------------------------------------------===//
+//
+// All of these need proper implementations.
+//
+//===----------------------------------------------------------------------===//
-class VectorTypeLoc : public TypeSpecTypeLoc<VectorTypeLoc, VectorType> {
+// FIXME: size expression and attribute locations (or keyword if we
+// ever fully support altivec syntax).
+class VectorTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
+ VectorTypeLoc,
+ VectorType> {
};
+// FIXME: size expression and attribute locations.
class ExtVectorTypeLoc : public InheritingConcreteTypeLoc<VectorTypeLoc,
ExtVectorTypeLoc,
ExtVectorType> {
};
+// FIXME: attribute locations.
// For some reason, this isn't a subtype of VectorType.
class DependentSizedExtVectorTypeLoc :
- public TypeSpecTypeLoc<DependentSizedExtVectorTypeLoc,
- DependentSizedExtVectorType> {
+ public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
+ DependentSizedExtVectorTypeLoc,
+ DependentSizedExtVectorType> {
};
-class FixedWidthIntTypeLoc : public TypeSpecTypeLoc<FixedWidthIntTypeLoc,
- FixedWidthIntType> {
+// FIXME: I'm not sure how you actually specify these; with attributes?
+class FixedWidthIntTypeLoc :
+ public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
+ FixedWidthIntTypeLoc,
+ FixedWidthIntType> {
};
-class ComplexTypeLoc : public TypeSpecTypeLoc<ComplexTypeLoc,
- ComplexType> {
+// FIXME: location of the '_Complex' keyword.
+class ComplexTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
+ ComplexTypeLoc,
+ ComplexType> {
};
-class TypeOfExprTypeLoc : public TypeSpecTypeLoc<TypeOfExprTypeLoc,
- TypeOfExprType> {
+// FIXME: location of the 'typeof' and parens (the expression is
+// carried by the type).
+class TypeOfExprTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
+ TypeOfExprTypeLoc,
+ TypeOfExprType> {
};
-class TypeOfTypeLoc : public TypeSpecTypeLoc<TypeOfTypeLoc, TypeOfType> {
+// FIXME: location of the 'typeof' and parens; also the TypeSourceInfo
+// for the inner type, or (maybe) just express that inline to the TypeLoc.
+class TypeOfTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
+ TypeOfTypeLoc,
+ TypeOfType> {
};
-class DecltypeTypeLoc : public TypeSpecTypeLoc<DecltypeTypeLoc, DecltypeType> {
-};
-
-class TagTypeLoc : public TypeSpecTypeLoc<TagTypeLoc, TagType> {
-};
-
-class RecordTypeLoc : public InheritingConcreteTypeLoc<TagTypeLoc,
- RecordTypeLoc,
- RecordType> {
-};
-
-class EnumTypeLoc : public InheritingConcreteTypeLoc<TagTypeLoc,
- EnumTypeLoc,
- EnumType> {
+// FIXME: location of the 'decltype' and parens.
+class DecltypeTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
+ DecltypeTypeLoc,
+ DecltypeType> {
};
-class ElaboratedTypeLoc : public TypeSpecTypeLoc<ElaboratedTypeLoc,
- ElaboratedType> {
+// FIXME: location of the tag keyword.
+class ElaboratedTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
+ ElaboratedTypeLoc,
+ ElaboratedType> {
};
-class QualifiedNameTypeLoc : public TypeSpecTypeLoc<QualifiedNameTypeLoc,
- QualifiedNameType> {
+// FIXME: locations for the nested name specifier; at the very least,
+// a SourceRange.
+class QualifiedNameTypeLoc :
+ public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
+ QualifiedNameTypeLoc,
+ QualifiedNameType> {
};
-class TypenameTypeLoc : public TypeSpecTypeLoc<TypenameTypeLoc,
- TypenameType> {
+// FIXME: locations for the typename keyword and nested name specifier.
+class TypenameTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
+ TypenameTypeLoc,
+ TypenameType> {
};
}
diff --git a/include/clang/AST/TypeLocBuilder.h b/include/clang/AST/TypeLocBuilder.h
index 00e2b7f83219..c3b1c68b1fb6 100644
--- a/include/clang/AST/TypeLocBuilder.h
+++ b/include/clang/AST/TypeLocBuilder.h
@@ -59,9 +59,35 @@ class TypeLocBuilder {
grow(Requested);
}
- /// Pushes space for a new TypeLoc onto the given type. Invalidates
+ /// Pushes space for a typespec TypeLoc. Invalidates any TypeLocs
+ /// previously retrieved from this builder.
+ TypeSpecTypeLoc pushTypeSpec(QualType T) {
+ size_t LocalSize = TypeSpecTypeLoc::LocalDataSize;
+ return cast<TypeSpecTypeLoc>(pushImpl(T, LocalSize));
+ }
+
+
+ /// Pushes space for a new TypeLoc of the given type. Invalidates
/// any TypeLocs previously retrieved from this builder.
template <class TyLocType> TyLocType push(QualType T) {
+ size_t LocalSize = cast<TyLocType>(TypeLoc(T, 0)).getLocalDataSize();
+ return cast<TyLocType>(pushImpl(T, LocalSize));
+ }
+
+ /// Creates a TypeSourceInfo for the given type.
+ TypeSourceInfo *getTypeSourceInfo(ASTContext& Context, QualType T) {
+#ifndef NDEBUG
+ assert(T == LastTy && "type doesn't match last type pushed!");
+#endif
+
+ size_t FullDataSize = Capacity - Index;
+ TypeSourceInfo *DI = Context.CreateTypeSourceInfo(T, FullDataSize);
+ memcpy(DI->getTypeLoc().getOpaqueData(), &Buffer[Index], FullDataSize);
+ return DI;
+ }
+
+private:
+ TypeLoc pushImpl(QualType T, size_t LocalSize) {
#ifndef NDEBUG
QualType TLast = TypeLoc(T, 0).getNextTypeLoc().getType();
assert(TLast == LastTy &&
@@ -69,8 +95,6 @@ class TypeLocBuilder {
LastTy = T;
#endif
- size_t LocalSize = cast<TyLocType>(TypeLoc(T, 0)).getLocalDataSize();
-
// If we need to grow, grow by a factor of 2.
if (LocalSize > Index) {
size_t RequiredCapacity = Capacity + (LocalSize - Index);
@@ -82,22 +106,9 @@ class TypeLocBuilder {
Index -= LocalSize;
- return cast<TyLocType>(TypeLoc(T, &Buffer[Index]));
- }
-
- /// Creates a DeclaratorInfo for the given type.
- DeclaratorInfo *getDeclaratorInfo(ASTContext& Context, QualType T) {
-#ifndef NDEBUG
- assert(T == LastTy && "type doesn't match last type pushed!");
-#endif
-
- size_t FullDataSize = Capacity - Index;
- DeclaratorInfo *DI = Context.CreateDeclaratorInfo(T, FullDataSize);
- memcpy(DI->getTypeLoc().getOpaqueData(), &Buffer[Index], FullDataSize);
- return DI;
+ return TypeLoc(T, &Buffer[Index]);
}
- private:
/// Grow to the given capacity.
void grow(size_t NewCapacity) {
assert(NewCapacity > Capacity);
diff --git a/include/clang/AST/TypeLocVisitor.h b/include/clang/AST/TypeLocVisitor.h
index a62bb3f853bc..95ec175a53a4 100644
--- a/include/clang/AST/TypeLocVisitor.h
+++ b/include/clang/AST/TypeLocVisitor.h
@@ -33,7 +33,7 @@ public:
case TypeLoc::CLASS: DISPATCH(CLASS##TypeLoc);
#include "clang/AST/TypeLocNodes.def"
}
- llvm::llvm_unreachable("unexpected type loc class!");
+ llvm_unreachable("unexpected type loc class!");
}
RetTy Visit(UnqualTypeLoc TyLoc) {
diff --git a/include/clang/AST/TypeNodes.def b/include/clang/AST/TypeNodes.def
index c2721236af02..b9d37992a670 100644
--- a/include/clang/AST/TypeNodes.def
+++ b/include/clang/AST/TypeNodes.def
@@ -71,6 +71,7 @@ TYPE(ExtVector, VectorType)
ABSTRACT_TYPE(Function, Type)
TYPE(FunctionProto, FunctionType)
TYPE(FunctionNoProto, FunctionType)
+DEPENDENT_TYPE(UnresolvedUsing, Type)
NON_CANONICAL_TYPE(Typedef, Type)
NON_CANONICAL_TYPE(TypeOfExpr, Type)
NON_CANONICAL_TYPE(TypeOf, Type)
diff --git a/include/clang/AST/TypeOrdering.h b/include/clang/AST/TypeOrdering.h
index 652f4f70bd16..1a050d29c860 100644
--- a/include/clang/AST/TypeOrdering.h
+++ b/include/clang/AST/TypeOrdering.h
@@ -50,13 +50,6 @@ namespace llvm {
static bool isEqual(clang::QualType LHS, clang::QualType RHS) {
return LHS == RHS;
}
-
- static bool isPod() {
- // QualType isn't *technically* a POD type. However, we can get
- // away with calling it a POD type since its copy constructor,
- // copy assignment operator, and destructor are all trivial.
- return true;
- }
};
}
diff --git a/include/clang/Analysis/PathDiagnostic.h b/include/clang/Analysis/PathDiagnostic.h
index cad702cbdb2e..970b523e1b43 100644
--- a/include/clang/Analysis/PathDiagnostic.h
+++ b/include/clang/Analysis/PathDiagnostic.h
@@ -179,9 +179,7 @@ private:
PathDiagnosticPiece& operator=(const PathDiagnosticPiece &P);
protected:
- PathDiagnosticPiece(const std::string& s, Kind k, DisplayHint hint = Below);
-
- PathDiagnosticPiece(const char* s, Kind k, DisplayHint hint = Below);
+ PathDiagnosticPiece(llvm::StringRef s, Kind k, DisplayHint hint = Below);
PathDiagnosticPiece(Kind k, DisplayHint hint = Below);
@@ -242,7 +240,7 @@ private:
PathDiagnosticLocation Pos;
public:
PathDiagnosticSpotPiece(const PathDiagnosticLocation &pos,
- const std::string& s,
+ llvm::StringRef s,
PathDiagnosticPiece::Kind k,
bool addPosRange = true)
: PathDiagnosticPiece(s, k), Pos(pos) {
@@ -261,11 +259,7 @@ class PathDiagnosticEventPiece : public PathDiagnosticSpotPiece {
public:
PathDiagnosticEventPiece(const PathDiagnosticLocation &pos,
- const std::string& s, bool addPosRange = true)
- : PathDiagnosticSpotPiece(pos, s, Event, addPosRange) {}
-
- PathDiagnosticEventPiece(const PathDiagnosticLocation &pos, const char* s,
- bool addPosRange = true)
+ llvm::StringRef s, bool addPosRange = true)
: PathDiagnosticSpotPiece(pos, s, Event, addPosRange) {}
~PathDiagnosticEventPiece();
@@ -280,14 +274,7 @@ class PathDiagnosticControlFlowPiece : public PathDiagnosticPiece {
public:
PathDiagnosticControlFlowPiece(const PathDiagnosticLocation &startPos,
const PathDiagnosticLocation &endPos,
- const std::string& s)
- : PathDiagnosticPiece(s, ControlFlow) {
- LPairs.push_back(PathDiagnosticLocationPair(startPos, endPos));
- }
-
- PathDiagnosticControlFlowPiece(const PathDiagnosticLocation &startPos,
- const PathDiagnosticLocation &endPos,
- const char* s)
+ llvm::StringRef s)
: PathDiagnosticPiece(s, ControlFlow) {
LPairs.push_back(PathDiagnosticLocationPair(startPos, endPos));
}
@@ -384,22 +371,19 @@ class PathDiagnostic : public llvm::FoldingSetNode {
public:
PathDiagnostic();
- PathDiagnostic(const char* bugtype, const char* desc, const char* category);
-
- PathDiagnostic(const std::string& bugtype, const std::string& desc,
- const std::string& category);
+ PathDiagnostic(llvm::StringRef bugtype, llvm::StringRef desc,
+ llvm::StringRef category);
~PathDiagnostic();
- const std::string& getDescription() const { return Desc; }
- const std::string& getBugType() const { return BugType; }
- const std::string& getCategory() const { return Category; }
+ llvm::StringRef getDescription() const { return Desc; }
+ llvm::StringRef getBugType() const { return BugType; }
+ llvm::StringRef getCategory() const { return Category; }
typedef std::deque<std::string>::const_iterator meta_iterator;
meta_iterator meta_begin() const { return OtherDesc.begin(); }
meta_iterator meta_end() const { return OtherDesc.end(); }
- void addMeta(const std::string& s) { OtherDesc.push_back(s); }
- void addMeta(const char* s) { OtherDesc.push_back(s); }
+ void addMeta(llvm::StringRef s) { OtherDesc.push_back(s); }
PathDiagnosticLocation getLocation() const {
assert(Size > 0 && "getLocation() requires a non-empty PathDiagnostic.");
diff --git a/include/clang/Analysis/PathSensitive/AnalysisContext.h b/include/clang/Analysis/PathSensitive/AnalysisContext.h
index 8b1a329c0335..abc33b778482 100644
--- a/include/clang/Analysis/PathSensitive/AnalysisContext.h
+++ b/include/clang/Analysis/PathSensitive/AnalysisContext.h
@@ -15,9 +15,10 @@
#ifndef LLVM_CLANG_ANALYSIS_ANALYSISCONTEXT_H
#define LLVM_CLANG_ANALYSIS_ANALYSISCONTEXT_H
-#include "clang/AST/Stmt.h"
+#include "clang/AST/Decl.h"
#include "llvm/ADT/OwningPtr.h"
#include "llvm/ADT/FoldingSet.h"
+#include "llvm/ADT/PointerUnion.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/Support/Allocator.h"
@@ -29,7 +30,10 @@ class CFG;
class LiveVariables;
class ParentMap;
class ImplicitParamDecl;
-
+class LocationContextManager;
+class BlockDataRegion;
+class StackFrameContext;
+
/// AnalysisContext contains the context data for the function or method under
/// analysis.
class AnalysisContext {
@@ -78,7 +82,7 @@ public:
class LocationContext : public llvm::FoldingSetNode {
public:
- enum ContextKind { StackFrame, Scope };
+ enum ContextKind { StackFrame, Scope, Block };
private:
ContextKind Kind;
@@ -91,7 +95,7 @@ protected:
: Kind(k), Ctx(ctx), Parent(parent) {}
public:
- virtual ~LocationContext() {}
+ virtual ~LocationContext();
ContextKind getKind() const { return Kind; }
@@ -114,36 +118,42 @@ public:
const ImplicitParamDecl *getSelfDecl() const {
return Ctx->getSelfDecl();
}
+
+ const StackFrameContext *getCurrentStackFrame() const;
+ const StackFrameContext *
+ getStackFrameForDeclContext(const DeclContext *DC) const;
- virtual void Profile(llvm::FoldingSetNodeID &ID) {
- Profile(ID, Kind, Ctx, Parent);
- }
-
- static void Profile(llvm::FoldingSetNodeID &ID, ContextKind k,
- AnalysisContext *ctx, const LocationContext *parent);
+ virtual void Profile(llvm::FoldingSetNodeID &ID) = 0;
static bool classof(const LocationContext*) { return true; }
+
+public:
+ static void ProfileCommon(llvm::FoldingSetNodeID &ID,
+ ContextKind ck,
+ AnalysisContext *ctx,
+ const LocationContext *parent,
+ const void* data);
};
class StackFrameContext : public LocationContext {
const Stmt *CallSite;
-public:
+ friend class LocationContextManager;
StackFrameContext(AnalysisContext *ctx, const LocationContext *parent,
const Stmt *s)
: LocationContext(StackFrame, ctx, parent), CallSite(s) {}
-
- virtual ~StackFrameContext() {}
+public:
+ ~StackFrameContext() {}
- Stmt const *getCallSite() const { return CallSite; }
-
- virtual void Profile(llvm::FoldingSetNodeID &ID) {
- Profile(ID, getAnalysisContext(), getParent(), CallSite);
- }
+ const Stmt *getCallSite() const { return CallSite; }
+ void Profile(llvm::FoldingSetNodeID &ID);
+
static void Profile(llvm::FoldingSetNodeID &ID, AnalysisContext *ctx,
- const LocationContext *parent, const Stmt *s);
+ const LocationContext *parent, const Stmt *s) {
+ ProfileCommon(ID, StackFrame, ctx, parent, s);
+ }
static bool classof(const LocationContext* Ctx) {
return Ctx->getKind() == StackFrame;
@@ -152,41 +162,91 @@ public:
class ScopeContext : public LocationContext {
const Stmt *Enter;
-
-public:
+
+ friend class LocationContextManager;
ScopeContext(AnalysisContext *ctx, const LocationContext *parent,
const Stmt *s)
: LocationContext(Scope, ctx, parent), Enter(s) {}
-
- virtual ~ScopeContext() {}
- virtual void Profile(llvm::FoldingSetNodeID &ID) {
- Profile(ID, getAnalysisContext(), getParent(), Enter);
- }
+public:
+ ~ScopeContext() {}
+
+ void Profile(llvm::FoldingSetNodeID &ID);
static void Profile(llvm::FoldingSetNodeID &ID, AnalysisContext *ctx,
- const LocationContext *parent, const Stmt *s);
+ const LocationContext *parent, const Stmt *s) {
+ ProfileCommon(ID, Scope, ctx, parent, s);
+ }
static bool classof(const LocationContext* Ctx) {
return Ctx->getKind() == Scope;
}
};
+class BlockInvocationContext : public LocationContext {
+ llvm::PointerUnion<const BlockDataRegion *, const BlockDecl *> Data;
+
+ 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) {}
+
+public:
+ ~BlockInvocationContext() {}
+
+ const BlockDataRegion *getBlockRegion() const {
+ return Data.is<const BlockDataRegion*>() ?
+ Data.get<const BlockDataRegion*>() : 0;
+ }
+
+ const BlockDecl *getBlockDecl() const;
+
+ 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);
+ }
+
+ static bool classof(const LocationContext* Ctx) {
+ return Ctx->getKind() == Block;
+ }
+};
+
class LocationContextManager {
llvm::FoldingSet<LocationContext> Contexts;
-
public:
~LocationContextManager();
- StackFrameContext *getStackFrame(AnalysisContext *ctx,
- const LocationContext *parent,
- const Stmt *s);
+ const StackFrameContext *getStackFrame(AnalysisContext *ctx,
+ const LocationContext *parent,
+ const Stmt *s);
- ScopeContext *getScope(AnalysisContext *ctx, const LocationContext *parent,
- const Stmt *s);
+ const ScopeContext *getScope(AnalysisContext *ctx,
+ 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:
+ template <typename LOC, typename DATA>
+ const LOC *getLocationContext(AnalysisContext *ctx,
+ const LocationContext *parent,
+ const DATA *d);
};
} // end clang namespace
diff --git a/include/clang/Analysis/PathSensitive/AnalysisManager.h b/include/clang/Analysis/PathSensitive/AnalysisManager.h
index 18eae9ac9f14..9ef5cce1002b 100644
--- a/include/clang/Analysis/PathSensitive/AnalysisManager.h
+++ b/include/clang/Analysis/PathSensitive/AnalysisManager.h
@@ -56,8 +56,7 @@ public:
const LangOptions &lang, PathDiagnosticClient *pd,
StoreManagerCreator storemgr,
ConstraintManagerCreator constraintmgr,
- bool displayProgress, bool vizdot, bool vizubi,
- bool purge, bool eager, bool trim)
+ bool vizdot, bool vizubi, bool purge, bool eager, bool trim)
: Ctx(ctx), Diags(diags), LangInfo(lang), PD(pd),
CreateStoreMgr(storemgr), CreateConstraintMgr(constraintmgr),
@@ -132,7 +131,7 @@ public:
}
// Get the top level stack frame.
- StackFrameContext *getStackFrame(Decl const *D) {
+ const StackFrameContext *getStackFrame(Decl const *D) {
return LocCtxMgr.getStackFrame(AnaCtxMgr.getContext(D), 0, 0);
}
diff --git a/include/clang/Analysis/PathSensitive/BugType.h b/include/clang/Analysis/PathSensitive/BugType.h
index 4f1523a5440d..b75a8189e54c 100644
--- a/include/clang/Analysis/PathSensitive/BugType.h
+++ b/include/clang/Analysis/PathSensitive/BugType.h
@@ -14,6 +14,7 @@
#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/PathSensitive/Checker.h b/include/clang/Analysis/PathSensitive/Checker.h
index 91a4b6d1b1eb..a625a7a25690 100644
--- a/include/clang/Analysis/PathSensitive/Checker.h
+++ b/include/clang/Analysis/PathSensitive/Checker.h
@@ -39,7 +39,7 @@ class CheckerContext {
SaveAndRestore<const void*> OldTag;
SaveAndRestore<ProgramPoint::Kind> OldPointKind;
SaveOr OldHasGen;
- const GRState *state;
+ const GRState *ST;
const Stmt *statement;
const unsigned size;
bool DoneEvaluating; // FIXME: This is not a permanent API change.
@@ -53,22 +53,14 @@ public:
OldTag(B.Tag, tag),
OldPointKind(B.PointKind, K),
OldHasGen(B.HasGeneratedNode),
- state(st), statement(stmt), size(Dst.size()),
- DoneEvaluating(false) {}
+ ST(st), statement(stmt), size(Dst.size()) {}
~CheckerContext();
-
- // FIXME: This were added to support CallAndMessageChecker to indicating
- // to GRExprEngine to "stop evaluating" a message expression under certain
- // cases. This is *not* meant to be a permanent API change, and was added
- // to aid in the transition of removing logic for checks from GRExprEngine.
- void setDoneEvaluating() {
- DoneEvaluating = true;
- }
- bool isDoneEvaluating() const {
- return DoneEvaluating;
+
+ GRExprEngine &getEngine() {
+ return Eng;
}
-
+
ConstraintManager &getConstraintManager() {
return Eng.getConstraintManager();
}
@@ -80,7 +72,7 @@ public:
ExplodedNodeSet &getNodeSet() { return Dst; }
GRStmtNodeBuilder &getNodeBuilder() { return B; }
ExplodedNode *&getPredecessor() { return Pred; }
- const GRState *getState() { return state ? state : B.GetState(Pred); }
+ const GRState *getState() { return ST ? ST : B.GetState(Pred); }
ASTContext &getASTContext() {
return Eng.getContext();
@@ -98,6 +90,10 @@ public:
return Eng.getValueManager();
}
+ SValuator &getSValuator() {
+ return Eng.getSValuator();
+ }
+
ExplodedNode *GenerateNode(bool autoTransition = true) {
assert(statement && "Only transitions with statements currently supported");
ExplodedNode *N = GenerateNodeImpl(statement, getState(), false);
@@ -115,6 +111,15 @@ public:
return N;
}
+ ExplodedNode *GenerateNode(const GRState *state, ExplodedNode *pred,
+ bool autoTransition = true) {
+ assert(statement && "Only transitions with statements currently supported");
+ ExplodedNode *N = GenerateNodeImpl(statement, state, pred, false);
+ if (N && autoTransition)
+ addTransition(N);
+ return N;
+ }
+
ExplodedNode *GenerateNode(const GRState *state, bool autoTransition = true) {
assert(statement && "Only transitions with statements currently supported");
ExplodedNode *N = GenerateNodeImpl(statement, state, false);
@@ -138,8 +143,7 @@ public:
void addTransition(const GRState *state) {
assert(state);
- if (state != getState() ||
- (state && state != B.GetState(Pred)))
+ if (state != getState() || (ST && ST != B.GetState(Pred)))
GenerateNode(state, true);
else
Dst.Add(Pred);
@@ -157,7 +161,14 @@ private:
node->markAsSink();
return node;
}
-
+
+ ExplodedNode *GenerateNodeImpl(const Stmt* stmt, const GRState *state,
+ ExplodedNode *pred, bool markAsSink) {
+ ExplodedNode *node = B.generateNode(stmt, state, pred);
+ if (markAsSink && node)
+ node->markAsSink();
+ return node;
+ }
};
class Checker {
@@ -165,7 +176,7 @@ private:
friend class GRExprEngine;
// FIXME: Remove the 'tag' option.
- bool GR_Visit(ExplodedNodeSet &Dst,
+ void GR_Visit(ExplodedNodeSet &Dst,
GRStmtNodeBuilder &Builder,
GRExprEngine &Eng,
const Stmt *S,
@@ -177,7 +188,22 @@ private:
_PreVisit(C, S);
else
_PostVisit(C, S);
- return C.isDoneEvaluating();
+ }
+
+ bool GR_EvalNilReceiver(ExplodedNodeSet &Dst, GRStmtNodeBuilder &Builder,
+ GRExprEngine &Eng, const ObjCMessageExpr *ME,
+ ExplodedNode *Pred, const GRState *state, void *tag) {
+ CheckerContext C(Dst, Builder, Eng, Pred, tag, ProgramPoint::PostStmtKind,
+ ME, state);
+ return EvalNilReceiver(C, ME);
+ }
+
+ bool GR_EvalCallExpr(ExplodedNodeSet &Dst, GRStmtNodeBuilder &Builder,
+ GRExprEngine &Eng, const CallExpr *CE,
+ ExplodedNode *Pred, void *tag) {
+ CheckerContext C(Dst, Builder, Eng, Pred, tag, ProgramPoint::PostStmtKind,
+ CE);
+ return EvalCallExpr(C, CE);
}
// FIXME: Remove the 'tag' option.
@@ -231,6 +257,14 @@ public:
virtual void VisitBranchCondition(GRBranchNodeBuilder &Builder,
GRExprEngine &Eng,
Stmt *Condition, void *tag) {}
+
+ virtual bool EvalNilReceiver(CheckerContext &C, const ObjCMessageExpr *ME) {
+ return false;
+ }
+
+ virtual bool EvalCallExpr(CheckerContext &C, const CallExpr *CE) {
+ return false;
+ }
};
} // end clang namespace
diff --git a/include/clang/Analysis/PathSensitive/GRExprEngine.h b/include/clang/Analysis/PathSensitive/GRExprEngine.h
index a7302c0602ec..8b20a823c6a1 100644
--- a/include/clang/Analysis/PathSensitive/GRExprEngine.h
+++ b/include/clang/Analysis/PathSensitive/GRExprEngine.h
@@ -209,8 +209,17 @@ public:
protected:
/// CheckerVisit - Dispatcher for performing checker-specific logic
/// at specific statements.
- bool CheckerVisit(Stmt *S, ExplodedNodeSet &Dst, ExplodedNodeSet &Src,
+ void CheckerVisit(Stmt *S, ExplodedNodeSet &Dst, ExplodedNodeSet &Src,
bool isPrevisit);
+
+ bool CheckerEvalCall(const CallExpr *CE,
+ ExplodedNodeSet &Dst,
+ ExplodedNode *Pred);
+
+ void CheckerEvalNilReceiver(const ObjCMessageExpr *ME,
+ ExplodedNodeSet &Dst,
+ const GRState *state,
+ ExplodedNode *Pred);
void CheckerVisitBind(const Stmt *AssignE, const Stmt *StoreE,
ExplodedNodeSet &Dst, ExplodedNodeSet &Src,
@@ -272,6 +281,13 @@ protected:
void VisitDeclRefExpr(DeclRefExpr* DR, ExplodedNode* Pred,
ExplodedNodeSet& Dst, bool asLValue);
+ /// VisitBlockDeclRefExpr - Transfer function logic for BlockDeclRefExprs.
+ void VisitBlockDeclRefExpr(BlockDeclRefExpr* DR, ExplodedNode* Pred,
+ ExplodedNodeSet& Dst, bool asLValue);
+
+ void VisitCommonDeclRefExpr(Expr* DR, const NamedDecl *D,ExplodedNode* Pred,
+ ExplodedNodeSet& Dst, bool asLValue);
+
/// VisitDeclStmt - Transfer function logic for DeclStmts.
void VisitDeclStmt(DeclStmt* DS, ExplodedNode* Pred, ExplodedNodeSet& Dst);
@@ -358,9 +374,10 @@ public:
}
protected:
- void EvalObjCMessageExpr(ExplodedNodeSet& Dst, ObjCMessageExpr* ME, ExplodedNode* Pred) {
+ void EvalObjCMessageExpr(ExplodedNodeSet& Dst, ObjCMessageExpr* ME,
+ ExplodedNode* Pred, const GRState *state) {
assert (Builder && "GRStmtNodeBuilder must be defined.");
- getTF().EvalObjCMessageExpr(Dst, *this, *Builder, ME, Pred);
+ getTF().EvalObjCMessageExpr(Dst, *this, *Builder, ME, Pred, state);
}
const GRState* MarkBranch(const GRState* St, Stmt* Terminator,
diff --git a/include/clang/Analysis/PathSensitive/GRState.h b/include/clang/Analysis/PathSensitive/GRState.h
index d8bc2411750f..421ebbf9bd5e 100644
--- a/include/clang/Analysis/PathSensitive/GRState.h
+++ b/include/clang/Analysis/PathSensitive/GRState.h
@@ -217,6 +217,7 @@ public:
/// for the compound literal and 'BegInit' and 'EndInit' represent an
/// array of initializer values.
const GRState* bindCompoundLiteral(const CompoundLiteralExpr* CL,
+ const LocationContext *LC,
SVal V) const;
const GRState *BindExpr(const Stmt *S, SVal V, bool Invalidate = true) const;
@@ -237,7 +238,8 @@ public:
/// Get the lvalue for a StringLiteral.
SVal getLValue(const StringLiteral *literal) const;
- SVal getLValue(const CompoundLiteralExpr *literal) const;
+ SVal getLValue(const CompoundLiteralExpr *literal,
+ const LocationContext *LC) const;
/// Get the lvalue for an ivar reference.
SVal getLValue(const ObjCIvarDecl *decl, SVal base) const;
@@ -609,9 +611,10 @@ inline const GRState *GRState::AssumeInBound(DefinedOrUnknownSVal Idx,
cast<DefinedSVal>(UpperBound), Assumption);
}
-inline const GRState *GRState::bindCompoundLiteral(const CompoundLiteralExpr* CL,
- SVal V) const {
- return getStateManager().StoreMgr->BindCompoundLiteral(this, CL, V);
+inline const GRState *
+GRState::bindCompoundLiteral(const CompoundLiteralExpr* CL,
+ const LocationContext *LC, SVal V) const {
+ return getStateManager().StoreMgr->BindCompoundLiteral(this, CL, LC, V);
}
inline const GRState *GRState::bindDecl(const VarRegion* VR, SVal IVal) const {
@@ -639,8 +642,9 @@ inline SVal GRState::getLValue(const StringLiteral *literal) const {
return getStateManager().StoreMgr->getLValueString(literal);
}
-inline SVal GRState::getLValue(const CompoundLiteralExpr *literal) const {
- return getStateManager().StoreMgr->getLValueCompoundLiteral(literal);
+inline SVal GRState::getLValue(const CompoundLiteralExpr *literal,
+ const LocationContext *LC) const {
+ return getStateManager().StoreMgr->getLValueCompoundLiteral(literal, LC);
}
inline SVal GRState::getLValue(const ObjCIvarDecl *D, SVal Base) const {
diff --git a/include/clang/Analysis/PathSensitive/GRTransferFuncs.h b/include/clang/Analysis/PathSensitive/GRTransferFuncs.h
index 40c1ed3224f4..2594618c16db 100644
--- a/include/clang/Analysis/PathSensitive/GRTransferFuncs.h
+++ b/include/clang/Analysis/PathSensitive/GRTransferFuncs.h
@@ -47,7 +47,8 @@ public:
GRExprEngine& Engine,
GRStmtNodeBuilder& Builder,
ObjCMessageExpr* ME,
- ExplodedNode* Pred) {}
+ ExplodedNode* Pred,
+ const GRState *state) {}
// Stores.
diff --git a/include/clang/Analysis/PathSensitive/MemRegion.h b/include/clang/Analysis/PathSensitive/MemRegion.h
index ed964978a44a..2fe5ea0cf3ab 100644
--- a/include/clang/Analysis/PathSensitive/MemRegion.h
+++ b/include/clang/Analysis/PathSensitive/MemRegion.h
@@ -35,6 +35,7 @@ namespace clang {
class MemRegionManager;
class MemSpaceRegion;
class LocationContext;
+class StackFrameContext;
class VarRegion;
//===----------------------------------------------------------------------===//
@@ -45,22 +46,37 @@ class VarRegion;
class MemRegion : public llvm::FoldingSetNode {
friend class MemRegionManager;
public:
- enum Kind { MemSpaceRegionKind,
- SymbolicRegionKind,
- AllocaRegionKind,
- // Typed regions.
- BEG_TYPED_REGIONS,
- FunctionTextRegionKind,
- BlockTextRegionKind,
- BlockDataRegionKind,
- CompoundLiteralRegionKind,
- StringRegionKind, ElementRegionKind,
- // Decl Regions.
- BEG_DECL_REGIONS,
- VarRegionKind, FieldRegionKind,
- ObjCIvarRegionKind, ObjCObjectRegionKind,
- END_DECL_REGIONS,
- END_TYPED_REGIONS };
+ enum Kind {
+ // Memory spaces.
+ BEG_MEMSPACES,
+ GenericMemSpaceRegionKind = BEG_MEMSPACES,
+ StackLocalsSpaceRegionKind,
+ StackArgumentsSpaceRegionKind,
+ HeapSpaceRegionKind,
+ UnknownSpaceRegionKind,
+ GlobalsSpaceRegionKind,
+ END_MEMSPACES = GlobalsSpaceRegionKind,
+ // Untyped regions.
+ SymbolicRegionKind,
+ AllocaRegionKind,
+ // Typed regions.
+ BEG_TYPED_REGIONS,
+ FunctionTextRegionKind = BEG_TYPED_REGIONS,
+ BlockTextRegionKind,
+ BlockDataRegionKind,
+ CompoundLiteralRegionKind,
+ StringRegionKind,
+ ElementRegionKind,
+ // Decl Regions.
+ BEG_DECL_REGIONS,
+ VarRegionKind = BEG_DECL_REGIONS,
+ FieldRegionKind,
+ ObjCIvarRegionKind,
+ ObjCObjectRegionKind,
+ END_DECL_REGIONS = ObjCObjectRegionKind,
+ END_TYPED_REGIONS = END_DECL_REGIONS
+ };
+
private:
const Kind kind;
@@ -111,25 +127,102 @@ public:
/// MemSpaceRegion - A memory region that represents and "memory space";
/// for example, the set of global variables, the stack frame, etc.
class MemSpaceRegion : public MemRegion {
- friend class MemRegionManager;
-
protected:
+ friend class MemRegionManager;
+
MemRegionManager *Mgr;
- MemSpaceRegion(MemRegionManager *mgr) : MemRegion(MemSpaceRegionKind),
- Mgr(mgr) {}
+ MemSpaceRegion(MemRegionManager *mgr, Kind k = GenericMemSpaceRegionKind)
+ : MemRegion(k), Mgr(mgr) {
+ assert(classof(this));
+ }
+
+ MemRegionManager* getMemRegionManager() const { return Mgr; }
+
+public:
+ bool isBoundable() const { return false; }
+
+ void Profile(llvm::FoldingSetNodeID &ID) const;
- MemRegionManager* getMemRegionManager() const {
- return Mgr;
+ static bool classof(const MemRegion *R) {
+ Kind k = R->getKind();
+ return k >= BEG_MEMSPACES && k <= END_MEMSPACES;
}
+};
+
+class GlobalsSpaceRegion : public MemSpaceRegion {
+ friend class MemRegionManager;
+ GlobalsSpaceRegion(MemRegionManager *mgr)
+ : MemSpaceRegion(mgr, GlobalsSpaceRegionKind) {}
public:
- void Profile(llvm::FoldingSetNodeID& ID) const;
+ static bool classof(const MemRegion *R) {
+ return R->getKind() == GlobalsSpaceRegionKind;
+ }
+};
+
+class HeapSpaceRegion : public MemSpaceRegion {
+ friend class MemRegionManager;
+
+ HeapSpaceRegion(MemRegionManager *mgr)
+ : MemSpaceRegion(mgr, HeapSpaceRegionKind) {}
+public:
+ static bool classof(const MemRegion *R) {
+ return R->getKind() == HeapSpaceRegionKind;
+ }
+};
+
+class UnknownSpaceRegion : public MemSpaceRegion {
+ friend class MemRegionManager;
+ UnknownSpaceRegion(MemRegionManager *mgr)
+ : MemSpaceRegion(mgr, UnknownSpaceRegionKind) {}
+public:
+ static bool classof(const MemRegion *R) {
+ return R->getKind() == UnknownSpaceRegionKind;
+ }
+};
+
+class StackSpaceRegion : public MemSpaceRegion {
+private:
+ const StackFrameContext *SFC;
- bool isBoundable() const { return false; }
+protected:
+ StackSpaceRegion(MemRegionManager *mgr, Kind k, const StackFrameContext *sfc)
+ : MemSpaceRegion(mgr, k), SFC(sfc) {
+ assert(classof(this));
+ }
- static bool classof(const MemRegion* R) {
- return R->getKind() == MemSpaceRegionKind;
+public:
+ const StackFrameContext *getStackFrame() const { return SFC; }
+
+ void Profile(llvm::FoldingSetNodeID &ID) const;
+
+ static bool classof(const MemRegion *R) {
+ Kind k = R->getKind();
+ return k >= StackLocalsSpaceRegionKind &&
+ k <= StackArgumentsSpaceRegionKind;
+ }
+};
+
+class StackLocalsSpaceRegion : public StackSpaceRegion {
+private:
+ friend class MemRegionManager;
+ StackLocalsSpaceRegion(MemRegionManager *mgr, const StackFrameContext *sfc)
+ : StackSpaceRegion(mgr, StackLocalsSpaceRegionKind, sfc) {}
+public:
+ static bool classof(const MemRegion *R) {
+ return R->getKind() == StackLocalsSpaceRegionKind;
+ }
+};
+
+class StackArgumentsSpaceRegion : public StackSpaceRegion {
+private:
+ friend class MemRegionManager;
+ StackArgumentsSpaceRegion(MemRegionManager *mgr, const StackFrameContext *sfc)
+ : StackSpaceRegion(mgr, StackArgumentsSpaceRegionKind, sfc) {}
+public:
+ static bool classof(const MemRegion *R) {
+ return R->getKind() == StackArgumentsSpaceRegionKind;
}
};
@@ -149,7 +242,7 @@ public:
bool isSubRegionOf(const MemRegion* R) const;
static bool classof(const MemRegion* R) {
- return R->getKind() > MemSpaceRegionKind;
+ return R->getKind() > END_MEMSPACES;
}
};
@@ -237,7 +330,7 @@ public:
static bool classof(const MemRegion* R) {
unsigned k = R->getKind();
- return k > BEG_TYPED_REGIONS && k < END_TYPED_REGIONS;
+ return k >= BEG_TYPED_REGIONS && k <= END_TYPED_REGIONS;
}
};
@@ -295,12 +388,17 @@ public:
/// like a closure a block captures the values of externally referenced
/// variables.
class BlockTextRegion : public CodeTextRegion {
+ friend class MemRegionManager;
+
const BlockDecl *BD;
+ AnalysisContext *AC;
CanQualType locTy;
-public:
- BlockTextRegion(const BlockDecl *bd, CanQualType lTy, const MemRegion* sreg)
- : CodeTextRegion(sreg, BlockTextRegionKind), BD(bd), locTy(lTy) {}
-
+
+ BlockTextRegion(const BlockDecl *bd, CanQualType lTy,
+ AnalysisContext *ac, const MemRegion* sreg)
+ : CodeTextRegion(sreg, BlockTextRegionKind), BD(bd), AC(ac), locTy(lTy) {}
+
+public:
QualType getLocationType(ASTContext &C) const {
return locTy;
}
@@ -308,13 +406,16 @@ public:
const BlockDecl *getDecl() const {
return BD;
}
+
+ AnalysisContext *getAnalysisContext() const { return AC; }
virtual void dumpToStream(llvm::raw_ostream& os) const;
void Profile(llvm::FoldingSetNodeID& ID) const;
static void ProfileRegion(llvm::FoldingSetNodeID& ID, const BlockDecl *BD,
- CanQualType, const MemRegion*);
+ CanQualType, const AnalysisContext*,
+ const MemRegion*);
static bool classof(const MemRegion* R) {
return R->getKind() == BlockTextRegionKind;
@@ -329,18 +430,45 @@ public:
/// variables.
/// BlockDataRegion - A region that represents code texts of blocks (closures).
class BlockDataRegion : public SubRegion {
+ friend class MemRegionManager;
const BlockTextRegion *BC;
- const LocationContext *LC;
+ const LocationContext *LC; // Can be null */
void *ReferencedVars;
-public:
- BlockDataRegion(const BlockTextRegion *bc,
- const LocationContext *lc,
+
+ BlockDataRegion(const BlockTextRegion *bc, const LocationContext *lc,
const MemRegion *sreg)
: SubRegion(sreg, BlockDataRegionKind), BC(bc), LC(lc), ReferencedVars(0) {}
+public:
const BlockTextRegion *getCodeRegion() const { return BC; }
- typedef const MemRegion * const * referenced_vars_iterator;
+ const BlockDecl *getDecl() const { return BC->getDecl(); }
+
+ class referenced_vars_iterator {
+ const MemRegion * const *R;
+ public:
+ explicit referenced_vars_iterator(const MemRegion * const *r) : R(r) {}
+
+ operator const MemRegion * const *() const {
+ return R;
+ }
+
+ const VarRegion* operator*() const {
+ return cast<VarRegion>(*R);
+ }
+
+ bool operator==(const referenced_vars_iterator &I) const {
+ return I.R == R;
+ }
+ bool operator!=(const referenced_vars_iterator &I) const {
+ return I.R != R;
+ }
+ referenced_vars_iterator& operator++() {
+ ++R;
+ return *this;
+ }
+ };
+
referenced_vars_iterator referenced_vars_begin() const;
referenced_vars_iterator referenced_vars_end() const;
@@ -348,9 +476,8 @@ public:
void Profile(llvm::FoldingSetNodeID& ID) const;
- static void ProfileRegion(llvm::FoldingSetNodeID& ID,
- const BlockTextRegion *BC,
- const LocationContext *LC, const MemRegion *);
+ static void ProfileRegion(llvm::FoldingSetNodeID&, const BlockTextRegion *,
+ const LocationContext *, const MemRegion *);
static bool classof(const MemRegion* R) {
return R->getKind() == BlockDataRegionKind;
@@ -473,25 +600,20 @@ public:
static bool classof(const MemRegion* R) {
unsigned k = R->getKind();
- return k > BEG_DECL_REGIONS && k < END_DECL_REGIONS;
+ return k >= BEG_DECL_REGIONS && k <= END_DECL_REGIONS;
}
};
class VarRegion : public DeclRegion {
friend class MemRegionManager;
- // Data.
- const LocationContext *LC;
-
// Constructors and private methods.
- VarRegion(const VarDecl* vd, const LocationContext *lC, const MemRegion* sReg)
- : DeclRegion(vd, sReg, VarRegionKind), LC(lC) {}
+ VarRegion(const VarDecl* vd, const MemRegion* sReg)
+ : DeclRegion(vd, sReg, VarRegionKind) {}
static void ProfileRegion(llvm::FoldingSetNodeID& ID, const VarDecl* VD,
- const LocationContext *LC,
const MemRegion *superRegion) {
DeclRegion::ProfileRegion(ID, VD, superRegion, VarRegionKind);
- ID.AddPointer(LC);
}
void Profile(llvm::FoldingSetNodeID& ID) const;
@@ -499,8 +621,8 @@ class VarRegion : public DeclRegion {
public:
const VarDecl *getDecl() const { return cast<VarDecl>(D); }
- const LocationContext *getLocationContext() const { return LC; }
-
+ const StackFrameContext *getStackFrame() const;
+
QualType getValueType(ASTContext& C) const {
// FIXME: We can cache this if needed.
return C.getCanonicalType(getDecl()->getType());
@@ -647,17 +769,24 @@ class MemRegionManager {
llvm::BumpPtrAllocator& A;
llvm::FoldingSet<MemRegion> Regions;
- MemSpaceRegion *globals;
- MemSpaceRegion *stack;
- MemSpaceRegion *stackArguments;
- MemSpaceRegion *heap;
- MemSpaceRegion *unknown;
+ GlobalsSpaceRegion *globals;
+
+ const StackFrameContext *cachedStackLocalsFrame;
+ StackLocalsSpaceRegion *cachedStackLocalsRegion;
+
+ const StackFrameContext *cachedStackArgumentsFrame;
+ StackArgumentsSpaceRegion *cachedStackArgumentsRegion;
+
+ HeapSpaceRegion *heap;
+ UnknownSpaceRegion *unknown;
MemSpaceRegion *code;
public:
MemRegionManager(ASTContext &c, llvm::BumpPtrAllocator& a)
- : C(c), A(a), globals(0), stack(0), stackArguments(0), heap(0),
- unknown(0), code(0) {}
+ : C(c), A(a), globals(0),
+ cachedStackLocalsFrame(0), cachedStackLocalsRegion(0),
+ cachedStackArgumentsFrame(0), cachedStackArgumentsRegion(0),
+ heap(0), unknown(0), code(0) {}
~MemRegionManager();
@@ -665,52 +794,60 @@ public:
llvm::BumpPtrAllocator &getAllocator() { return A; }
- /// getStackRegion - Retrieve the memory region associated with the
- /// current stack frame.
- MemSpaceRegion *getStackRegion();
+ /// getStackLocalsRegion - Retrieve the memory region associated with the
+ /// specified stack frame.
+ const StackLocalsSpaceRegion *
+ getStackLocalsRegion(const StackFrameContext *STC);
/// getStackArgumentsRegion - Retrieve the memory region associated with
- /// function/method arguments of the current stack frame.
- MemSpaceRegion *getStackArgumentsRegion();
+ /// function/method arguments of the specified stack frame.
+ const StackArgumentsSpaceRegion *
+ getStackArgumentsRegion(const StackFrameContext *STC);
/// getGlobalsRegion - Retrieve the memory region associated with
/// all global variables.
- MemSpaceRegion *getGlobalsRegion();
+ const GlobalsSpaceRegion *getGlobalsRegion();
/// getHeapRegion - Retrieve the memory region associated with the
/// generic "heap".
- MemSpaceRegion *getHeapRegion();
+ const HeapSpaceRegion *getHeapRegion();
/// getUnknownRegion - Retrieve the memory region associated with unknown
/// memory space.
- MemSpaceRegion *getUnknownRegion();
+ const MemSpaceRegion *getUnknownRegion();
- MemSpaceRegion *getCodeRegion();
+ const MemSpaceRegion *getCodeRegion();
/// getAllocaRegion - Retrieve a region associated with a call to alloca().
- AllocaRegion *getAllocaRegion(const Expr* Ex, unsigned Cnt);
+ const AllocaRegion *getAllocaRegion(const Expr* Ex, unsigned Cnt,
+ const LocationContext *LC);
/// getCompoundLiteralRegion - Retrieve the region associated with a
/// given CompoundLiteral.
- CompoundLiteralRegion*
- getCompoundLiteralRegion(const CompoundLiteralExpr* CL);
+ const CompoundLiteralRegion*
+ getCompoundLiteralRegion(const CompoundLiteralExpr* CL,
+ const LocationContext *LC);
/// getSymbolicRegion - Retrieve or create a "symbolic" memory region.
- SymbolicRegion* getSymbolicRegion(SymbolRef sym);
+ const SymbolicRegion* getSymbolicRegion(SymbolRef sym);
- StringRegion* getStringRegion(const StringLiteral* Str);
+ const StringRegion* getStringRegion(const StringLiteral* Str);
/// getVarRegion - Retrieve or create the memory region associated with
/// a specified VarDecl and LocationContext.
- VarRegion* getVarRegion(const VarDecl *D, const LocationContext *LC);
+ const VarRegion* getVarRegion(const VarDecl *D, const LocationContext *LC);
+ /// getVarRegion - Retrieve or create the memory region associated with
+ /// a specified VarDecl and super region.
+ const VarRegion* getVarRegion(const VarDecl *D, const MemRegion *superR);
+
/// getElementRegion - Retrieve the memory region associated with the
/// associated element type, index, and super region.
- ElementRegion *getElementRegion(QualType elementType, SVal Idx,
+ const ElementRegion *getElementRegion(QualType elementType, SVal Idx,
const MemRegion *superRegion,
ASTContext &Ctx);
- ElementRegion *getElementRegionWithSuper(const ElementRegion *ER,
+ const ElementRegion *getElementRegionWithSuper(const ElementRegion *ER,
const MemRegion *superRegion) {
return getElementRegion(ER->getElementType(), ER->getIndex(),
superRegion, ER->getContext());
@@ -720,31 +857,44 @@ public:
/// a specified FieldDecl. 'superRegion' corresponds to the containing
/// memory region (which typically represents the memory representing
/// a structure or class).
- FieldRegion *getFieldRegion(const FieldDecl* fd,
- const MemRegion* superRegion);
+ const FieldRegion *getFieldRegion(const FieldDecl* fd,
+ const MemRegion* superRegion);
- FieldRegion *getFieldRegionWithSuper(const FieldRegion *FR,
- const MemRegion *superRegion) {
+ const FieldRegion *getFieldRegionWithSuper(const FieldRegion *FR,
+ const MemRegion *superRegion) {
return getFieldRegion(FR->getDecl(), superRegion);
}
/// getObjCObjectRegion - Retrieve or create the memory region associated with
/// the instance of a specified Objective-C class.
- ObjCObjectRegion* getObjCObjectRegion(const ObjCInterfaceDecl* ID,
- const MemRegion* superRegion);
+ const ObjCObjectRegion* getObjCObjectRegion(const ObjCInterfaceDecl* ID,
+ const MemRegion* superRegion);
/// getObjCIvarRegion - Retrieve or create the memory region associated with
/// a specified Objective-c instance variable. 'superRegion' corresponds
/// to the containing region (which typically represents the Objective-C
/// object).
- ObjCIvarRegion *getObjCIvarRegion(const ObjCIvarDecl* ivd,
- const MemRegion* superRegion);
+ const ObjCIvarRegion *getObjCIvarRegion(const ObjCIvarDecl* ivd,
+ const MemRegion* superRegion);
- FunctionTextRegion *getFunctionTextRegion(const FunctionDecl *FD);
- BlockTextRegion *getBlockTextRegion(const BlockDecl *BD, CanQualType locTy);
- BlockDataRegion *getBlockDataRegion(const BlockTextRegion *bc,
- const LocationContext *lc);
+ const FunctionTextRegion *getFunctionTextRegion(const FunctionDecl *FD);
+ const BlockTextRegion *getBlockTextRegion(const BlockDecl *BD,
+ CanQualType locTy,
+ AnalysisContext *AC);
+
+ /// getBlockDataRegion - Get the memory region associated with an instance
+ /// of a block. Unlike many other MemRegions, the LocationContext*
+ /// argument is allowed to be NULL for cases where we have no known
+ /// context.
+ const BlockDataRegion *getBlockDataRegion(const BlockTextRegion *bc,
+ const LocationContext *lc = NULL);
+ bool isGlobalsRegion(const MemRegion* R) {
+ assert(R);
+ return R == globals;
+ }
+
+private:
template <typename RegionTy, typename A1>
RegionTy* getRegion(const A1 a1);
@@ -758,13 +908,15 @@ public:
RegionTy* getSubRegion(const A1 a1, const A2 a2,
const MemRegion* superRegion);
- bool isGlobalsRegion(const MemRegion* R) {
- assert(R);
- return R == globals;
- }
-
-private:
- MemSpaceRegion* LazyAllocate(MemSpaceRegion*& region);
+ template <typename RegionTy, typename A1, typename A2, typename A3>
+ RegionTy* getSubRegion(const A1 a1, const A2 a2, const A3 a3,
+ const MemRegion* superRegion);
+
+ template <typename REG>
+ const REG* LazyAllocate(REG*& region);
+
+ template <typename REG, typename ARG>
+ const REG* LazyAllocate(REG*& region, ARG a);
};
//===----------------------------------------------------------------------===//
@@ -774,157 +926,6 @@ private:
inline ASTContext& MemRegion::getContext() const {
return getMemRegionManager()->getContext();
}
-
-template<typename RegionTy> struct MemRegionManagerTrait;
-
-template <typename RegionTy, typename A1>
-RegionTy* MemRegionManager::getRegion(const A1 a1) {
-
- const typename MemRegionManagerTrait<RegionTy>::SuperRegionTy *superRegion =
- MemRegionManagerTrait<RegionTy>::getSuperRegion(*this, a1);
-
- llvm::FoldingSetNodeID ID;
- RegionTy::ProfileRegion(ID, a1, superRegion);
- void* InsertPos;
- RegionTy* R = cast_or_null<RegionTy>(Regions.FindNodeOrInsertPos(ID,
- InsertPos));
-
- if (!R) {
- R = (RegionTy*) A.Allocate<RegionTy>();
- new (R) RegionTy(a1, superRegion);
- Regions.InsertNode(R, InsertPos);
- }
-
- return R;
-}
-
-template <typename RegionTy, typename A1>
-RegionTy* MemRegionManager::getSubRegion(const A1 a1,
- const MemRegion *superRegion) {
- llvm::FoldingSetNodeID ID;
- RegionTy::ProfileRegion(ID, a1, superRegion);
- void* InsertPos;
- RegionTy* R = cast_or_null<RegionTy>(Regions.FindNodeOrInsertPos(ID,
- InsertPos));
-
- if (!R) {
- R = (RegionTy*) A.Allocate<RegionTy>();
- new (R) RegionTy(a1, superRegion);
- Regions.InsertNode(R, InsertPos);
- }
-
- return R;
-}
-
-template <typename RegionTy, typename A1, typename A2>
-RegionTy* MemRegionManager::getRegion(const A1 a1, const A2 a2) {
-
- const typename MemRegionManagerTrait<RegionTy>::SuperRegionTy *superRegion =
- MemRegionManagerTrait<RegionTy>::getSuperRegion(*this, a1, a2);
-
- llvm::FoldingSetNodeID ID;
- RegionTy::ProfileRegion(ID, a1, a2, superRegion);
- void* InsertPos;
- RegionTy* R = cast_or_null<RegionTy>(Regions.FindNodeOrInsertPos(ID,
- InsertPos));
-
- if (!R) {
- R = (RegionTy*) A.Allocate<RegionTy>();
- new (R) RegionTy(a1, a2, superRegion);
- Regions.InsertNode(R, InsertPos);
- }
-
- return R;
-}
-
-template <typename RegionTy, typename A1, typename A2>
-RegionTy* MemRegionManager::getSubRegion(const A1 a1, const A2 a2,
- const MemRegion *superRegion) {
-
- llvm::FoldingSetNodeID ID;
- RegionTy::ProfileRegion(ID, a1, a2, superRegion);
- void* InsertPos;
- RegionTy* R = cast_or_null<RegionTy>(Regions.FindNodeOrInsertPos(ID,
- InsertPos));
-
- if (!R) {
- R = (RegionTy*) A.Allocate<RegionTy>();
- new (R) RegionTy(a1, a2, superRegion);
- Regions.InsertNode(R, InsertPos);
- }
-
- return R;
-}
-
-//===----------------------------------------------------------------------===//
-// Traits for constructing regions.
-//===----------------------------------------------------------------------===//
-
-template <> struct MemRegionManagerTrait<AllocaRegion> {
- typedef MemRegion SuperRegionTy;
- static const SuperRegionTy* getSuperRegion(MemRegionManager& MRMgr,
- const Expr *, unsigned) {
- return MRMgr.getStackRegion();
- }
-};
-
-template <> struct MemRegionManagerTrait<CompoundLiteralRegion> {
- typedef MemRegion SuperRegionTy;
- static const SuperRegionTy* getSuperRegion(MemRegionManager& MRMgr,
- const CompoundLiteralExpr *CL) {
-
- return CL->isFileScope() ? MRMgr.getGlobalsRegion()
- : MRMgr.getStackRegion();
- }
-};
-
-template <> struct MemRegionManagerTrait<StringRegion> {
- typedef MemSpaceRegion SuperRegionTy;
- static const SuperRegionTy* getSuperRegion(MemRegionManager& MRMgr,
- const StringLiteral*) {
- return MRMgr.getGlobalsRegion();
- }
-};
-
-template <> struct MemRegionManagerTrait<VarRegion> {
- typedef MemRegion SuperRegionTy;
- static const SuperRegionTy* getSuperRegion(MemRegionManager &MRMgr,
- const VarDecl *D,
- const LocationContext *LC) {
-
- // FIXME: Make stack regions have a location context?
-
- if (D->hasLocalStorage()) {
- return isa<ParmVarDecl>(D) || isa<ImplicitParamDecl>(D)
- ? MRMgr.getStackArgumentsRegion() : MRMgr.getStackRegion();
- }
-
- return MRMgr.getGlobalsRegion();
- }
-};
-
-template <> struct MemRegionManagerTrait<SymbolicRegion> {
- typedef MemRegion SuperRegionTy;
- static const SuperRegionTy* getSuperRegion(MemRegionManager& MRMgr,
- SymbolRef) {
- return MRMgr.getUnknownRegion();
- }
-};
-
-template<> struct MemRegionManagerTrait<FunctionTextRegion> {
- typedef MemSpaceRegion SuperRegionTy;
- static const SuperRegionTy* getSuperRegion(MemRegionManager& MRMgr,
- const FunctionDecl*) {
- return MRMgr.getCodeRegion();
- }
-};
-template<> struct MemRegionManagerTrait<BlockTextRegion> {
- typedef MemSpaceRegion SuperRegionTy;
- static const SuperRegionTy* getSuperRegion(MemRegionManager& MRMgr,
- const BlockDecl*, CanQualType) {
- return MRMgr.getCodeRegion();
- }
-};
} // end clang namespace
diff --git a/include/clang/Analysis/PathSensitive/Store.h b/include/clang/Analysis/PathSensitive/Store.h
index 55fa83d9ecc3..648710f7ad12 100644
--- a/include/clang/Analysis/PathSensitive/Store.h
+++ b/include/clang/Analysis/PathSensitive/Store.h
@@ -73,8 +73,9 @@ public:
/// for the compound literal and 'BegInit' and 'EndInit' represent an
/// array of initializer values.
virtual const GRState *BindCompoundLiteral(const GRState *state,
- const CompoundLiteralExpr* cl,
- SVal v) = 0;
+ 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.
@@ -93,7 +94,8 @@ public:
virtual SVal getLValueString(const StringLiteral* sl) = 0;
- virtual SVal getLValueCompoundLiteral(const CompoundLiteralExpr* cl) = 0;
+ SVal getLValueCompoundLiteral(const CompoundLiteralExpr* cl,
+ const LocationContext *LC);
virtual SVal getLValueIvar(const ObjCIvarDecl* decl, SVal base) = 0;
@@ -147,6 +149,12 @@ public:
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);
// FIXME: Make out-of-line.
virtual const GRState *setExtent(const GRState *state,
diff --git a/include/clang/Analysis/PathSensitive/SymbolManager.h b/include/clang/Analysis/PathSensitive/SymbolManager.h
index 167a102e94ec..8eb319647953 100644
--- a/include/clang/Analysis/PathSensitive/SymbolManager.h
+++ b/include/clang/Analysis/PathSensitive/SymbolManager.h
@@ -28,10 +28,12 @@ namespace llvm {
}
namespace clang {
- class MemRegion;
- class TypedRegion;
class ASTContext;
class BasicValueFactory;
+ class MemRegion;
+ class TypedRegion;
+ class VarRegion;
+ class StackFrameContext;
}
namespace clang {
@@ -332,10 +334,13 @@ class SymbolReaper {
SetTy TheDead;
LiveVariables& Liveness;
SymbolManager& SymMgr;
+ const StackFrameContext *CurrentStackFrame;
public:
- SymbolReaper(LiveVariables& liveness, SymbolManager& symmgr)
- : Liveness(liveness), SymMgr(symmgr) {}
+ SymbolReaper(LiveVariables& liveness, SymbolManager& symmgr,
+ const StackFrameContext *currentStackFrame)
+ : Liveness(liveness), SymMgr(symmgr), CurrentStackFrame(currentStackFrame)
+ {}
~SymbolReaper() {}
@@ -345,10 +350,8 @@ public:
return Liveness.isLive(Loc, ExprVal);
}
- bool isLive(const Stmt* Loc, const VarDecl* VD) const {
- return Liveness.isLive(Loc, VD);
- }
-
+ bool isLive(const Stmt* Loc, const VarRegion *VR) const;
+
void markLive(SymbolRef sym);
bool maybeDead(SymbolRef sym);
diff --git a/include/clang/Analysis/ProgramPoint.h b/include/clang/Analysis/ProgramPoint.h
index 78827dfabe2f..5abe1abd5d39 100644
--- a/include/clang/Analysis/ProgramPoint.h
+++ b/include/clang/Analysis/ProgramPoint.h
@@ -333,10 +333,11 @@ static bool isEqual(const clang::ProgramPoint& L,
return L == R;
}
-static bool isPod() {
- return true;
-}
};
+
+template <>
+struct isPodLike<clang::ProgramPoint> { static const bool value = true; };
+
} // end namespace llvm
#endif
diff --git a/include/clang/Analysis/Support/BumpVector.h b/include/clang/Analysis/Support/BumpVector.h
index b23a80ed481a..48851d0f2637 100644
--- a/include/clang/Analysis/Support/BumpVector.h
+++ b/include/clang/Analysis/Support/BumpVector.h
@@ -166,7 +166,7 @@ public:
private:
/// grow - double the size of the allocated memory, guaranteeing space for at
/// least one more element or MinSize if specified.
- void grow(BumpVectorContext &C, size_type MinSize = 0);
+ void grow(BumpVectorContext &C, size_type MinSize = 1);
void construct_range(T *S, T *E, const T &Elt) {
for (; S != E; ++S)
diff --git a/include/clang/Basic/Builtins.def b/include/clang/Basic/Builtins.def
index 98c703d94e92..e700cdeb5d6c 100644
--- a/include/clang/Basic/Builtins.def
+++ b/include/clang/Basic/Builtins.def
@@ -118,51 +118,51 @@ BUILTIN(__builtin_powf, "fff" , "nc")
BUILTIN(__builtin_powl, "LdLdLd", "nc")
// Standard unary libc/libm functions with double/float/long double variants:
-BUILTIN(__builtin_acos , "dd" , "nc")
-BUILTIN(__builtin_acosf, "ff" , "nc")
-BUILTIN(__builtin_acosl, "LdLd", "nc")
-BUILTIN(__builtin_asin , "dd" , "nc")
-BUILTIN(__builtin_asinf, "ff" , "nc")
-BUILTIN(__builtin_asinl, "LdLd", "nc")
-BUILTIN(__builtin_atan , "dd" , "nc")
-BUILTIN(__builtin_atanf, "ff" , "nc")
-BUILTIN(__builtin_atanl, "LdLd", "nc")
-BUILTIN(__builtin_ceil , "dd" , "nc")
-BUILTIN(__builtin_ceilf, "ff" , "nc")
-BUILTIN(__builtin_ceill, "LdLd", "nc")
-BUILTIN(__builtin_cos , "dd" , "nc")
-BUILTIN(__builtin_cosf, "ff" , "nc")
-BUILTIN(__builtin_cosh , "dd" , "nc")
-BUILTIN(__builtin_coshf, "ff" , "nc")
-BUILTIN(__builtin_coshl, "LdLd", "nc")
-BUILTIN(__builtin_cosl, "LdLd", "nc")
-BUILTIN(__builtin_exp , "dd" , "nc")
-BUILTIN(__builtin_expf, "ff" , "nc")
-BUILTIN(__builtin_expl, "LdLd", "nc")
-BUILTIN(__builtin_floor , "dd" , "nc")
-BUILTIN(__builtin_floorf, "ff" , "nc")
-BUILTIN(__builtin_floorl, "LdLd", "nc")
-BUILTIN(__builtin_log , "dd" , "nc")
-BUILTIN(__builtin_log10 , "dd" , "nc")
-BUILTIN(__builtin_log10f, "ff" , "nc")
-BUILTIN(__builtin_log10l, "LdLd", "nc")
-BUILTIN(__builtin_logf, "ff" , "nc")
-BUILTIN(__builtin_logl, "LdLd", "nc")
-BUILTIN(__builtin_sin , "dd" , "nc")
-BUILTIN(__builtin_sinf, "ff" , "nc")
-BUILTIN(__builtin_sinh , "dd" , "nc")
-BUILTIN(__builtin_sinhf, "ff" , "nc")
-BUILTIN(__builtin_sinhl, "LdLd", "nc")
-BUILTIN(__builtin_sinl, "LdLd", "nc")
-BUILTIN(__builtin_sqrt , "dd" , "nc")
-BUILTIN(__builtin_sqrtf, "ff" , "nc")
-BUILTIN(__builtin_sqrtl, "LdLd", "nc")
-BUILTIN(__builtin_tan , "dd" , "nc")
-BUILTIN(__builtin_tanf, "ff" , "nc")
-BUILTIN(__builtin_tanh , "dd" , "nc")
-BUILTIN(__builtin_tanhf, "ff" , "nc")
-BUILTIN(__builtin_tanhl, "LdLd", "nc")
-BUILTIN(__builtin_tanl, "LdLd", "nc")
+BUILTIN(__builtin_acos , "dd" , "Fnc")
+BUILTIN(__builtin_acosf, "ff" , "Fnc")
+BUILTIN(__builtin_acosl, "LdLd", "Fnc")
+BUILTIN(__builtin_asin , "dd" , "Fnc")
+BUILTIN(__builtin_asinf, "ff" , "Fnc")
+BUILTIN(__builtin_asinl, "LdLd", "Fnc")
+BUILTIN(__builtin_atan , "dd" , "Fnc")
+BUILTIN(__builtin_atanf, "ff" , "Fnc")
+BUILTIN(__builtin_atanl, "LdLd", "Fnc")
+BUILTIN(__builtin_ceil , "dd" , "Fnc")
+BUILTIN(__builtin_ceilf, "ff" , "Fnc")
+BUILTIN(__builtin_ceill, "LdLd", "Fnc")
+BUILTIN(__builtin_cos , "dd" , "Fnc")
+BUILTIN(__builtin_cosf, "ff" , "Fnc")
+BUILTIN(__builtin_cosh , "dd" , "Fnc")
+BUILTIN(__builtin_coshf, "ff" , "Fnc")
+BUILTIN(__builtin_coshl, "LdLd", "Fnc")
+BUILTIN(__builtin_cosl, "LdLd", "Fnc")
+BUILTIN(__builtin_exp , "dd" , "Fnc")
+BUILTIN(__builtin_expf, "ff" , "Fnc")
+BUILTIN(__builtin_expl, "LdLd", "Fnc")
+BUILTIN(__builtin_floor , "dd" , "Fnc")
+BUILTIN(__builtin_floorf, "ff" , "Fnc")
+BUILTIN(__builtin_floorl, "LdLd", "Fnc")
+BUILTIN(__builtin_log , "dd" , "Fnc")
+BUILTIN(__builtin_log10 , "dd" , "Fnc")
+BUILTIN(__builtin_log10f, "ff" , "Fnc")
+BUILTIN(__builtin_log10l, "LdLd", "Fnc")
+BUILTIN(__builtin_logf, "ff" , "Fnc")
+BUILTIN(__builtin_logl, "LdLd", "Fnc")
+BUILTIN(__builtin_sin , "dd" , "Fnc")
+BUILTIN(__builtin_sinf, "ff" , "Fnc")
+BUILTIN(__builtin_sinh , "dd" , "Fnc")
+BUILTIN(__builtin_sinhf, "ff" , "Fnc")
+BUILTIN(__builtin_sinhl, "LdLd", "Fnc")
+BUILTIN(__builtin_sinl, "LdLd", "Fnc")
+BUILTIN(__builtin_sqrt , "dd" , "Fnc")
+BUILTIN(__builtin_sqrtf, "ff" , "Fnc")
+BUILTIN(__builtin_sqrtl, "LdLd", "Fnc")
+BUILTIN(__builtin_tan , "dd" , "Fnc")
+BUILTIN(__builtin_tanf, "ff" , "Fnc")
+BUILTIN(__builtin_tanh , "dd" , "Fnc")
+BUILTIN(__builtin_tanhf, "ff" , "Fnc")
+BUILTIN(__builtin_tanhl, "LdLd", "Fnc")
+BUILTIN(__builtin_tanl, "LdLd", "Fnc")
// C99 complex builtins
BUILTIN(__builtin_cabs, "dXd", "Fnc")
diff --git a/include/clang/Basic/BuiltinsX86.def b/include/clang/Basic/BuiltinsX86.def
index bbf42ee8c7fe..6315c16dd80a 100644
--- a/include/clang/Basic/BuiltinsX86.def
+++ b/include/clang/Basic/BuiltinsX86.def
@@ -250,7 +250,7 @@ BUILTIN(__builtin_ia32_pmaddwd128, "V8sV8sV8s", "")
BUILTIN(__builtin_ia32_monitor, "vv*UiUi", "")
BUILTIN(__builtin_ia32_mwait, "vUiUi", "")
BUILTIN(__builtin_ia32_lddqu, "V16ccC*", "")
-BUILTIN(__builtin_ia32_palignr128, "V2LLiV2LLiV2LLic", "")
+BUILTIN(__builtin_ia32_palignr128, "V16cV16cV16cc", "")
BUILTIN(__builtin_ia32_palignr, "V1LLiV1LLiV1LLic", "")
BUILTIN(__builtin_ia32_insertps128, "V4fV4fV4fi", "")
diff --git a/include/clang/Basic/Diagnostic.h b/include/clang/Basic/Diagnostic.h
index 00a5bc6e937d..b2523f28d5e0 100644
--- a/include/clang/Basic/Diagnostic.h
+++ b/include/clang/Basic/Diagnostic.h
@@ -238,7 +238,6 @@ public:
DiagnosticClient *getClient() { return Client; }
const DiagnosticClient *getClient() const { return Client; }
-
/// pushMappings - Copies the current DiagMappings and pushes the new copy
/// onto the top of the stack.
void pushMappings();
@@ -319,7 +318,7 @@ public:
/// getCustomDiagID - Return an ID for a diagnostic with the specified message
/// and level. If this is the first request for this diagnosic, it is
/// registered and created, otherwise the existing ID is returned.
- unsigned getCustomDiagID(Level L, const char *Message);
+ unsigned getCustomDiagID(Level L, llvm::StringRef Message);
/// ConvertArgToString - This method converts a diagnostic argument (as an
diff --git a/include/clang/Basic/DiagnosticCommonKinds.td b/include/clang/Basic/DiagnosticCommonKinds.td
index 9a342b592ca5..f319cf231a26 100644
--- a/include/clang/Basic/DiagnosticCommonKinds.td
+++ b/include/clang/Basic/DiagnosticCommonKinds.td
@@ -26,8 +26,8 @@ def note_type_being_defined : Note<
/// e.g. to specify the '(' when we expected a ')'.
def note_matching : Note<"to match this '%0'">;
-def note_using_decl : Note<"using">;
-def note_also_found_decl : Note<"also found">;
+def note_using : Note<"using">;
+def note_also_found : Note<"also found">;
// Parse && Lex
def err_expected_colon : Error<"expected ':'">;
diff --git a/include/clang/Basic/DiagnosticDriverKinds.td b/include/clang/Basic/DiagnosticDriverKinds.td
index 3f7d114dda60..efbc787ef0ee 100644
--- a/include/clang/Basic/DiagnosticDriverKinds.td
+++ b/include/clang/Basic/DiagnosticDriverKinds.td
@@ -60,6 +60,8 @@ def err_drv_I_dash_not_supported : Error<
def err_drv_unknown_argument : Error<"unknown argument: '%0'">;
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 warn_drv_input_file_unused : Warning<
"%0: '%1' input unused when '%2' is present">;
@@ -70,7 +72,7 @@ def warn_drv_unused_argument : Warning<
def warn_drv_pipe_ignored_with_save_temps : Warning<
"-pipe ignored because -save-temps specified">;
def warn_drv_not_using_clang_cpp : Warning<
- "not using the clang prepreprocessor due to user override">;
+ "not using the clang preprocessor due to user override">;
def warn_drv_not_using_clang_cxx : Warning<
"not using the clang compiler for C++ inputs">;
def warn_drv_not_using_clang_arch : Warning<
diff --git a/include/clang/Basic/DiagnosticFrontendKinds.td b/include/clang/Basic/DiagnosticFrontendKinds.td
index cbc287c58c89..252900d18b3f 100644
--- a/include/clang/Basic/DiagnosticFrontendKinds.td
+++ b/include/clang/Basic/DiagnosticFrontendKinds.td
@@ -15,8 +15,8 @@ def err_fe_error_reading_stdin : Error<"error reading stdin">;
def err_fe_error_backend : Error<"error in backend: %0">, DefaultFatal;
def err_fe_invalid_ast_file : Error<"invalid AST file: '%0'">, DefaultFatal;
def err_fe_invalid_ast_action : Error<"invalid action for AST input">, DefaultFatal;
-def err_fe_invalid_code_complete_file
- : Error<"cannot locate code-completion file %0">, DefaultFatal;
+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_dependency_file_requires_MT : Error<
@@ -29,6 +29,36 @@ def err_fe_unable_to_find_fixit_file : Error<
"FIX-IT could not find file '%0'">;
def err_fe_invalid_plugin_name : Error<
"unable to find plugin '%0'">;
+def err_fe_expected_compiler_job : Error<
+ "unable to handle compilation, expected exactly one compiler job in '%0'">;
+def err_fe_expected_clang_command : Error<
+ "expected a clang compiler command">;
+def err_fe_remap_missing_to_file : Error<
+ "could not remap file '%0' to the contents of file '%1'">, DefaultFatal;
+def err_fe_remap_missing_from_file : Error<
+ "could not remap from missing file '%0'">, DefaultFatal;
+def err_fe_unable_to_load_pch : Error<
+ "unable to load PCH file">;
+def err_fe_unable_to_load_plugin : Error<
+ "unable to load plugin '%0': '%1'">;
+def err_fe_unable_to_create_target : Error<
+ "unable to create target: '%0'">;
+def err_fe_unable_to_interface_with_target : Error<
+ "unable to interface with target machine">;
+def err_fe_unable_to_read_pch_file : Error<
+ "unable to read PCH file: '%0'">;
+def err_fe_not_a_pch_file : Error<
+ "input is not a PCH file: '%0'">;
+def err_fe_pch_malformed_block : Error<
+ "malformed block record in PCH file: '%0'">;
+def err_fe_pch_error_at_end_block : Error<
+ "error at end of module block in PCH file: '%0'">;
+def err_fe_unable_to_open_output : Error<
+ "unable to open output file '%0': '%1'">;
+def err_fe_pth_file_has_no_source_header : Error<
+ "PTH file '%0' does not designate an original source header file for -include-pth">;
+def warn_fe_macro_contains_embedded_newline : Warning<
+ "macro '%0' contains embedded newline, text after the newline is ignored.">;
def err_verify_bogus_characters : Error<
"bogus characters before '{{' in expected string">;
@@ -45,6 +75,8 @@ def note_fixit_in_macro : Note<
def note_fixit_failed : Note<
"FIX-IT unable to apply suggested code changes">;
def note_fixit_unfixed_error : Note<"FIX-IT detected an error it cannot fix">;
+def note_fixit_main_file_unchanged : Note<
+ "main file unchanged">;
def warn_fixit_no_changes : Note<
"FIX-IT detected errors it could not fix; no output will be generated">;
diff --git a/include/clang/Basic/DiagnosticGroups.td b/include/clang/Basic/DiagnosticGroups.td
index c1c833cf5c66..761478abd3d4 100644
--- a/include/clang/Basic/DiagnosticGroups.td
+++ b/include/clang/Basic/DiagnosticGroups.td
@@ -113,6 +113,7 @@ def Reorder : DiagGroup<"reorder">;
def UndeclaredSelector : DiagGroup<"undeclared-selector">;
def SuperSubClassMismatch : DiagGroup<"super-class-method-mismatch">;
def : DiagGroup<"variadic-macros">;
+def VariadicMacros : DiagGroup<"variadic-macros">;
def VectorConversions : DiagGroup<"vector-conversions">; // clang specific
def VolatileRegisterVar : DiagGroup<"volatile-register-var">;
def : DiagGroup<"write-strings">;
diff --git a/include/clang/Basic/DiagnosticLexKinds.td b/include/clang/Basic/DiagnosticLexKinds.td
index 39123d9b371a..d8b5f2dad3c9 100644
--- a/include/clang/Basic/DiagnosticLexKinds.td
+++ b/include/clang/Basic/DiagnosticLexKinds.td
@@ -51,6 +51,9 @@ def err_empty_character : Error<"empty character constant">;
def err_unterminated_block_comment : Error<"unterminated /* comment">;
def err_invalid_character_to_charify : Error<
"invalid argument to convert to character">;
+
+def err_conflict_marker : Error<"version control conflict marker in file">;
+
def ext_multichar_character_literal : ExtWarn<
"multi-character character constant">, InGroup<MultiChar>;
def ext_four_char_character_literal : Extension<
@@ -150,9 +153,10 @@ def ext_pp_comma_expr : Extension<"comma operator in operand of #if">;
def ext_pp_bad_vaargs_use : Extension<
"__VA_ARGS__ can only appear in the expansion of a C99 variadic macro">;
def ext_pp_macro_redef : ExtWarn<"%0 macro redefined">;
-def ext_variadic_macro : Extension<"variadic macros were introduced in C99">;
+def ext_variadic_macro : Extension<"variadic macros were introduced in C99">,
+ InGroup<VariadicMacros>;
def ext_named_variadic_macro : Extension<
- "named variadic macros are a GNU extension">;
+ "named variadic macros are a GNU extension">, InGroup<VariadicMacros>;
def ext_embedded_directive : Extension<
"embedding a directive within macro arguments is not portable">;
def ext_missing_varargs_arg : Extension<
@@ -160,18 +164,11 @@ def ext_missing_varargs_arg : Extension<
def ext_empty_fnmacro_arg : Extension<
"empty macro arguments were standardized in C99">;
-def ext_pp_base_file : Extension<"__BASE_FILE__ is a language extension">;
-def ext_pp_include_level : Extension<
- "__INCLUDE_LEVEL__ is a language extension">;
-def ext_pp_timestamp : Extension<"__TIMESTAMP__ is a language extension">;
-def ext_pp_counter : Extension<
- "__COUNTER__ is a language extension">;
-
def err_pp_invalid_directive : Error<"invalid preprocessing directive">;
def err_pp_hash_error : Error<"#error%0">;
def err_pp_file_not_found : Error<"'%0' file not found">, DefaultFatal;
def err_pp_error_opening_file : Error<
- "error opening file '%0'">, DefaultFatal;
+ "error opening file '%0': %1">, DefaultFatal;
def err_pp_empty_filename : Error<"empty filename">;
def err_pp_include_too_deep : Error<"#include nested too deeply">;
def err_pp_expects_filename : Error<"expected \"FILENAME\" or <FILENAME>">;
diff --git a/include/clang/Basic/DiagnosticParseKinds.td b/include/clang/Basic/DiagnosticParseKinds.td
index 43107044720e..bf188cf14f91 100644
--- a/include/clang/Basic/DiagnosticParseKinds.td
+++ b/include/clang/Basic/DiagnosticParseKinds.td
@@ -166,6 +166,8 @@ def err_use_of_tag_name_without_tag : Error<
"use of tagged type %0 without '%1' tag">;
def err_expected_ident_in_using : Error<
"expected an identifier in using directive">;
+def err_unexected_colon_in_nested_name_spec : Error<
+ "unexpected ':' in nested name specifier">;
/// Objective-C parser diagnostics
def err_objc_no_attributes_on_category : Error<
diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td
index a0e03fed1600..a890323e6c0d 100644
--- a/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/include/clang/Basic/DiagnosticSemaKinds.td
@@ -105,7 +105,11 @@ def err_using_typename_non_type : Error<
"'typename' keyword used on a non-type">;
def err_using_dependent_value_is_type : Error<
"dependent using declaration resolved to type without 'typename'">;
-def err_using_decl_nested_name_specifier_is_not_a_base_class : Error<
+def err_using_decl_nested_name_specifier_is_not_class : Error<
+ "using declaration in class refers into '%0', which is not a class">;
+def err_using_decl_nested_name_specifier_is_current_class : Error<
+ "using declaration refers to its own class">;
+def err_using_decl_nested_name_specifier_is_not_base_class : Error<
"using declaration refers into '%0', which is not a base class of %1">;
def err_using_decl_can_not_refer_to_class_member : Error<
"using declaration can not refer to class member">;
@@ -117,8 +121,17 @@ def err_using_decl_destructor : Error<
"using declaration can not refer to a destructor">;
def err_using_decl_template_id : Error<
"using declaration can not refer to a template specialization">;
-def note_using_decl_target : Note<
- "target of using declaration">;
+def note_using_decl_target : Note<"target of using declaration">;
+def note_using_decl_conflict : Note<"conflicting declaration">;
+def err_using_decl_redeclaration : Error<"redeclaration of using decl">;
+def err_using_decl_conflict : Error<
+ "target of using declaration conflicts with declaration already in scope">;
+def err_using_decl_conflict_reverse : Error<
+ "declaration conflicts with target of using declaration already in scope">;
+def note_using_decl : Note<"%select{|previous }0using declaration">;
+
+def warn_access_decl_deprecated : Warning<
+ "access declarations are deprecated; use using declarations instead">;
def err_invalid_thread : Error<
"'__thread' is only allowed on variable declarations">;
@@ -186,7 +199,6 @@ def warn_pragma_pack_invalid_alignment : Warning<
"expected #pragma pack parameter to be '1', '2', '4', '8', or '16'">;
// Follow the MSVC implementation.
def warn_pragma_pack_show : Warning<"value of #pragma pack(show) == %0">;
-// FIXME: Dehardcode.
def warn_pragma_pack_pop_identifer_and_alignment : Warning<
"specifying both a name and alignment to 'pop' is undefined">;
def warn_pragma_pack_pop_failed : Warning<"#pragma pack(pop, ...) failed: %0">;
@@ -441,7 +453,8 @@ def err_implicit_object_parameter_init : Error<
"of type %1">;
def note_field_decl : Note<"member is declared here">;
-def note_previous_class_decl : Note<
+def note_bitfield_decl : Note<"bit-field is declared here">;
+def note_previous_decl : Note<
"%0 declared here">;
def note_member_synthesized_at : Note<
"implicit default %select{constructor|copy constructor|"
@@ -521,14 +534,35 @@ def err_lvalue_to_rvalue_ambig_ref : Error<"rvalue reference cannot bind to lval
def err_not_reference_to_const_init : Error<
"non-const lvalue reference to type %0 cannot be initialized "
"with a %1 of type %2">;
+def err_lvalue_reference_bind_to_temporary : Error<
+ "non-const lvalue reference to type %0 cannot bind to a temporary of type "
+ "%1">;
+def err_lvalue_reference_bind_to_unrelated : Error<
+ "non-const lvalue reference to type %0 cannot bind to a value of unrelated "
+ "type %1">;
+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<
+ "reference to type %0 could not bind to an %select{rvalue|lvalue}1 of type "
+ "%2">;
+def err_reference_bind_init_list : Error<
+ "reference to type %0 cannot bind to an initializer list">;
+def err_init_list_bad_dest_type : Error<
+ "%select{|non-aggregate }0type %1 cannot be initialized with an initializer "
+ "list">;
+
// FIXME: passing in an English string as %1!
def err_reference_init_drops_quals : Error<
"initialization of reference to type %0 with a %1 of type %2 drops "
"qualifiers">;
+def err_reference_bind_to_bitfield : Error<
+ "%select{non-const|volatile}0 reference cannot bind to bit-field %1">;
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_has_multiple_inits : Error<
+ "reference cannot be initialized with multiple values">;
def err_init_non_aggr_init_list : Error<
"initialization of non-aggregate type %0 with an initializer list">;
def err_init_reference_member_uninitialized : Error<
@@ -934,6 +968,11 @@ def err_template_variable_noparams : Error<
"extraneous 'template<>' in declaration of variable %0">;
def err_template_tag_noparams : Error<
"extraneous 'template<>' in declaration of %0 %1">;
+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<
@@ -1261,7 +1300,10 @@ def warn_missing_prototype : Warning<
"no previous prototype for function %0">,
InGroup<DiagGroup<"missing-prototypes">>, DefaultIgnore;
def err_redefinition : Error<"redefinition of %0">;
-
+def err_definition_of_implicitly_declared_member : Error<
+ "definition of implicitly declared %select{constructor|copy constructor|"
+ "copy assignment operator|destructor}1">;
+
def warn_redefinition_of_typedef : Warning<
"redefinition of typedef %0 is invalid in C">,
InGroup<DiagGroup<"typedef-redefinition"> >, DefaultError;
@@ -1515,6 +1557,8 @@ def err_typecheck_member_reference_ivar : Error<
"%0 does not have a member named %1">;
def err_typecheck_member_reference_arrow : Error<
"member reference type %0 is not a pointer">;
+def err_typecheck_member_reference_suggestion : Error<
+ "member reference type %0 is %select{a|not a}1 pointer; maybe you meant to use '%select{->|.}1'?">;
def err_typecheck_member_reference_type : Error<
"cannot refer to type member %0 with '%select{.|->}1'">;
def err_typecheck_member_reference_unknown : Error<
@@ -1564,6 +1608,9 @@ def warn_tentative_incomplete_array : Warning<
def err_typecheck_incomplete_array_needs_initializer : Error<
"definition of variable with array type needs an explicit size "
"or an initializer">;
+def err_array_init_not_init_list : Error<
+ "array initializater must be an initializer "
+ "list%select{| or string literal}0">;
def err_realimag_invalid_type : Error<"invalid type %0 to %1 operator">;
def err_typecheck_sclass_fscope : Error<
@@ -1649,6 +1696,7 @@ def warn_printf_nonliteral : Warning<
def err_unexpected_interface : Error<
"unexpected interface name %0: expected expression">;
+def err_ref_non_value : Error<"%0 does not refer to a value">;
def err_property_not_found : Error<
"property %0 not found on object of type %1">;
def ext_gnu_void_ptr : Extension<
@@ -1849,7 +1897,10 @@ def err_typecheck_bool_condition : Error<
def err_typecheck_ambiguous_condition : Error<
"conversion from %0 to %1 is ambiguous">;
def err_typecheck_nonviable_condition : Error<
- "no viable conversion from %0 to %1 is possible">;
+ "no viable conversion from %0 to %1">;
+def err_typecheck_deleted_function : Error<
+ "conversion function from %0 to %1 invokes a deleted function">;
+
def err_expected_class_or_namespace : Error<"expected a class or namespace">;
def err_invalid_declarator_scope : Error<
"definition or redeclaration of %0 not in a namespace enclosing %1">;
@@ -1963,7 +2014,8 @@ def err_cannot_pass_objc_interface_to_vararg : Error<
def warn_cannot_pass_non_pod_arg_to_vararg : Warning<
"cannot pass object of non-POD type %0 through variadic "
- "%select{function|block|method|constructor}1; call will abort at runtime">;
+ "%select{function|block|method|constructor}1; call will abort at runtime">,
+ InGroup<DiagGroup<"non-pod-varargs">>, DefaultError;
def err_typecheck_call_invalid_ordered_compare : Error<
"ordered compare requires two args of floating point type (%0 and %1)">;
@@ -2047,12 +2099,6 @@ def err_overload_expr_requires_non_zero_constant : Error<
def err_overload_incorrect_fntype : Error<
"argument is not a function, or has wrong number of parameters">;
-// FIXME: PASSING TYPES AS STRING.
-def err_overload_no_match : Error<
- "no matching overload found for arguments of type '%0'">;
-def err_overload_multiple_match : Error<
- "more than one matching function found in __builtin_overload">;
-
// C++ member initializers.
def err_only_constructors_take_base_inits : Error<
"only constructors take base initializers">;
@@ -2176,10 +2222,6 @@ def err_operator_overload_needs_class_or_enum : Error<
def err_operator_overload_variadic : Error<"overloaded %0 cannot be variadic">;
def err_operator_overload_static : Error<
"overloaded %0 cannot be a static member function">;
-def err_operator_new_param_type : Error<
- "%0 takes type size_t (%1) as first parameter">;
-def err_operator_new_result_type : Error<
- "%0 must return type %1">;
def err_operator_overload_default_arg : Error<
"parameter of overloaded %0 cannot have a default argument">;
def err_operator_overload_must_be : Error<
@@ -2192,6 +2234,31 @@ def err_operator_overload_post_incdec_must_be_int : Error<
"parameter of overloaded post-%select{increment|decrement}1 operator must "
"have type 'int' (not %0)">;
+// C++ allocation and deallocation functions.
+def err_operator_new_delete_declared_in_namespace : Error<
+ "%0 cannot be declared inside a namespace">;
+def err_operator_new_delete_declared_static : Error<
+ "%0 cannot be declared static in global scope">;
+def err_operator_new_delete_invalid_result_type : Error<
+ "%0 must return type %1">;
+def err_operator_new_delete_dependent_result_type : Error<
+ "%0 cannot have a dependent return type; use %1 instead">;
+def err_operator_new_delete_too_few_parameters : Error<
+ "%0 must have at least one parameter.">;
+def err_operator_new_delete_template_too_few_parameters : Error<
+ "%0 template must have at least two parameters.">;
+
+def err_operator_new_dependent_param_type : Error<
+ "%0 cannot take a dependent type as first parameter; "
+ "use size_t (%1) instead">;
+def err_operator_new_param_type : Error<
+ "%0 takes type size_t (%1) as first parameter">;
+def err_operator_new_default_arg: Error<
+ "parameter of %0 cannot have a default argument">;
+def err_operator_delete_dependent_param_type : Error<
+ "%0 cannot take a dependent type as first parameter; use %1 instead">;
+def err_operator_delete_param_type : Error<
+ "%0 takes type %1 as first parameter">;
// C++ conversion functions
def err_conv_function_not_member : Error<
@@ -2371,7 +2438,9 @@ def err_altivec_empty_initializer : Error<"expected initializer">;
def err_stack_const_level : Error<
"level argument for a stack address builtin must be constant">;
-def err_prefetch_invalid_argument : Error<
+def err_prefetch_invalid_arg_type : Error<
+ "argument to __builtin_prefetch must be of integer type">;
+def err_prefetch_invalid_arg_ice : Error<
"argument to __builtin_prefetch must be a constant integer">;
def err_argument_invalid_range : Error<
"argument should be a value from %0 to %1">;
diff --git a/include/clang/Basic/FileManager.h b/include/clang/Basic/FileManager.h
index 5e7ac4f3c859..d0e0118d99d6 100644
--- a/include/clang/Basic/FileManager.h
+++ b/include/clang/Basic/FileManager.h
@@ -14,6 +14,7 @@
#ifndef LLVM_CLANG_FILEMANAGER_H
#define LLVM_CLANG_FILEMANAGER_H
+#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/OwningPtr.h"
@@ -151,6 +152,9 @@ class FileManager {
///
unsigned NextFileUID;
+ /// \brief The virtual files that we have allocated.
+ llvm::SmallVector<FileEntry *, 4> VirtualFileEntries;
+
// Statistics.
unsigned NumDirLookups, NumFileLookups;
unsigned NumDirCacheMisses, NumFileCacheMisses;
@@ -199,6 +203,11 @@ public:
const FileEntry *getFile(const char *FilenameStart,
const char *FilenameEnd);
+ /// \brief Retrieve a file entry for a "virtual" file that acts as
+ /// if there were a file with the given name on disk. The file
+ /// itself is not accessed.
+ const FileEntry *getVirtualFile(const llvm::StringRef &Filename,
+ off_t Size, time_t ModificationTime);
void PrintStats() const;
};
diff --git a/include/clang/Basic/IdentifierTable.h b/include/clang/Basic/IdentifierTable.h
index 53939500e72a..75a7b8192c5a 100644
--- a/include/clang/Basic/IdentifierTable.h
+++ b/include/clang/Basic/IdentifierTable.h
@@ -532,9 +532,11 @@ struct DenseMapInfo<clang::Selector> {
static bool isEqual(clang::Selector LHS, clang::Selector RHS) {
return LHS == RHS;
}
-
- static bool isPod() { return true; }
};
+
+template <>
+struct isPodLike<clang::Selector> { static const bool value = true; };
+
// Provide PointerLikeTypeTraits for IdentifierInfo pointers, which
// are not guaranteed to be 8-byte aligned.
diff --git a/include/clang/Basic/LangOptions.h b/include/clang/Basic/LangOptions.h
index a16a27103b67..e17279e2664a 100644
--- a/include/clang/Basic/LangOptions.h
+++ b/include/clang/Basic/LangOptions.h
@@ -46,7 +46,7 @@ public:
unsigned LaxVectorConversions : 1;
unsigned AltiVec : 1; // Support AltiVec-style vector initializers.
unsigned Exceptions : 1; // Support exception handling.
- unsigned Rtti : 1; // Support rtti information.
+ unsigned RTTI : 1; // Support RTTI information.
unsigned NeXTRuntime : 1; // Use NeXT runtime.
unsigned Freestanding : 1; // Freestanding implementation
@@ -92,6 +92,7 @@ public:
unsigned ElideConstructors : 1; // Whether C++ copy constructors should be
// elided if possible.
+ unsigned CatchUndefined :1; // Generate code to check for undefined ops.
private:
unsigned GC : 2; // Objective-C Garbage Collection modes. We
// declare this enum as unsigned because MSVC
@@ -125,7 +126,7 @@ public:
CXXOperatorNames = PascalStrings = WritableStrings = 0;
Exceptions = Freestanding = NoBuiltin = 0;
NeXTRuntime = 1;
- Rtti = 1;
+ RTTI = 1;
LaxVectorConversions = 1;
HeinousExtensions = 0;
AltiVec = OpenCL = StackProtector = 0;
@@ -160,6 +161,7 @@ public:
CharIsSigned = 1;
ShortWChar = 0;
+ CatchUndefined = 0;
}
GCMode getGCMode() const { return (GCMode) GC; }
diff --git a/include/clang/Basic/PartialDiagnostic.h b/include/clang/Basic/PartialDiagnostic.h
index 9960d5beb5c1..ae11a755cce4 100644
--- a/include/clang/Basic/PartialDiagnostic.h
+++ b/include/clang/Basic/PartialDiagnostic.h
@@ -51,11 +51,11 @@ class PartialDiagnostic {
/// This is used when the argument is not an std::string. The specific value
/// is mangled into an intptr_t and the intepretation depends on exactly
/// what sort of argument kind it is.
- mutable intptr_t DiagArgumentsVal[MaxArguments];
+ intptr_t DiagArgumentsVal[MaxArguments];
/// DiagRanges - The list of ranges added to this diagnostic. It currently
/// only support 10 ranges, could easily be extended if needed.
- mutable const SourceRange *DiagRanges[10];
+ SourceRange DiagRanges[10];
};
/// DiagID - The diagnostic ID.
@@ -81,25 +81,40 @@ class PartialDiagnostic {
assert(DiagStorage->NumDiagRanges <
llvm::array_lengthof(DiagStorage->DiagRanges) &&
"Too many arguments to diagnostic!");
- DiagStorage->DiagRanges[DiagStorage->NumDiagRanges++] = &R;
+ DiagStorage->DiagRanges[DiagStorage->NumDiagRanges++] = R;
}
- void operator=(const PartialDiagnostic &); // DO NOT IMPLEMENT
-
public:
PartialDiagnostic(unsigned DiagID)
: DiagID(DiagID), DiagStorage(0) { }
PartialDiagnostic(const PartialDiagnostic &Other)
- : DiagID(Other.DiagID), DiagStorage(Other.DiagStorage) {
- Other.DiagID = 0;
- Other.DiagStorage = 0;
+ : DiagID(Other.DiagID), DiagStorage(0)
+ {
+ if (Other.DiagStorage)
+ DiagStorage = new Storage(*Other.DiagStorage);
+ }
+
+ PartialDiagnostic &operator=(const PartialDiagnostic &Other) {
+ DiagID = Other.DiagID;
+ if (Other.DiagStorage) {
+ if (DiagStorage)
+ *DiagStorage = *Other.DiagStorage;
+ else
+ DiagStorage = new Storage(*Other.DiagStorage);
+ } else {
+ delete DiagStorage;
+ DiagStorage = 0;
+ }
+
+ return *this;
}
~PartialDiagnostic() {
delete DiagStorage;
}
+
unsigned getDiagID() const { return DiagID; }
void Emit(const DiagnosticBuilder &DB) const {
@@ -114,7 +129,7 @@ public:
// Add all ranges.
for (unsigned i = 0, e = DiagStorage->NumDiagRanges; i != e; ++i)
- DB.AddSourceRange(*DiagStorage->DiagRanges[i]);
+ DB.AddSourceRange(DiagStorage->DiagRanges[i]);
}
friend const PartialDiagnostic &operator<<(const PartialDiagnostic &PD,
diff --git a/include/clang/Basic/SourceLocation.h b/include/clang/Basic/SourceLocation.h
index 28cf2db9bc25..36baf5feecce 100644
--- a/include/clang/Basic/SourceLocation.h
+++ b/include/clang/Basic/SourceLocation.h
@@ -21,6 +21,7 @@ namespace llvm {
class MemoryBuffer;
class raw_ostream;
template <typename T> struct DenseMapInfo;
+ template <typename T> struct isPodLike;
}
namespace clang {
@@ -296,9 +297,12 @@ namespace llvm {
static bool isEqual(clang::FileID LHS, clang::FileID RHS) {
return LHS == RHS;
}
-
- static bool isPod() { return true; }
};
+
+ template <>
+ struct isPodLike<clang::SourceLocation> { static const bool value = true; };
+ template <>
+ struct isPodLike<clang::FileID> { static const bool value = true; };
} // end namespace llvm
diff --git a/include/clang/Basic/SourceManager.h b/include/clang/Basic/SourceManager.h
index 7e9ac531017e..b4cf959dc551 100644
--- a/include/clang/Basic/SourceManager.h
+++ b/include/clang/Basic/SourceManager.h
@@ -54,9 +54,6 @@ namespace SrcMgr {
/// file. This is owned by the ContentCache object.
mutable const llvm::MemoryBuffer *Buffer;
- /// The line and column at which we should truncate the file.
- unsigned TruncateAtLine, TruncateAtColumn;
-
public:
/// Reference to the file entry. This reference does not own
/// the FileEntry object. It is possible for this to be NULL if
@@ -72,13 +69,10 @@ namespace SrcMgr {
/// if SourceLineCache is non-null.
unsigned NumLines;
- /// FirstFID - First FileID that was created for this ContentCache.
- /// Represents the first source inclusion of the file associated with this
- /// ContentCache.
- mutable FileID FirstFID;
-
- /// getBuffer - Returns the memory buffer for the associated content.
- const llvm::MemoryBuffer *getBuffer() const;
+ /// getBuffer - Returns the memory buffer for the associated content. If
+ /// there is an error opening this buffer the first time, this manufactures
+ /// a temporary buffer and returns a non-empty error string.
+ const llvm::MemoryBuffer *getBuffer(std::string *ErrorStr = 0) const;
/// getSize - Returns the size of the content encapsulated by this
/// ContentCache. This can be the size of the source file or the size of an
@@ -96,28 +90,19 @@ namespace SrcMgr {
Buffer = B;
}
- /// \brief Truncate this file at the given line and column.
- ///
- /// \param Line the line on which to truncate the current file (1-based).
- /// \param Column the column at which to truncate the current file.
- /// (1-based).
- void truncateAt(unsigned Line, unsigned Column);
-
- /// \brief Determines whether the file was artificially truncated with
- /// truncateAt().
- bool isTruncated() const { return TruncateAtLine && TruncateAtColumn; }
-
+ /// \brief Replace the existing buffer (which will be deleted)
+ /// with the given buffer.
+ void replaceBuffer(const llvm::MemoryBuffer *B);
+
ContentCache(const FileEntry *Ent = 0)
- : Buffer(0), TruncateAtLine(0), TruncateAtColumn(0), Entry(Ent),
- SourceLineCache(0), NumLines(0) {}
+ : Buffer(0), Entry(Ent), SourceLineCache(0), NumLines(0) {}
~ContentCache();
/// The copy ctor does not allow copies where source object has either
/// a non-NULL Buffer or SourceLineCache. Ownership of allocated memory
/// is not transfered, so this is a logical error.
- ContentCache(const ContentCache &RHS)
- : Buffer(0), TruncateAtLine(0), TruncateAtColumn(0), SourceLineCache(0) {
+ ContentCache(const ContentCache &RHS) : Buffer(0), SourceLineCache(0) {
Entry = RHS.Entry;
assert (RHS.Buffer == 0 && RHS.SourceLineCache == 0
@@ -347,19 +332,13 @@ class SourceManager {
mutable FileID LastRFIDForBeforeTUCheck;
mutable bool LastResForBeforeTUCheck;
- // Keep track of the file/line/column that we should truncate.
- const FileEntry *TruncateFile;
- unsigned TruncateAtLine;
- unsigned TruncateAtColumn;
-
// SourceManager doesn't support copy construction.
explicit SourceManager(const SourceManager&);
void operator=(const SourceManager&);
public:
SourceManager()
- : ExternalSLocEntries(0), LineTable(0), NumLinearScans(0),
- NumBinaryProbes(0), TruncateFile(0), TruncateAtLine(0),
- TruncateAtColumn(0) {
+ : ExternalSLocEntries(0), LineTable(0), NumLinearScans(0),
+ NumBinaryProbes(0) {
clearIDTables();
}
~SourceManager();
@@ -428,14 +407,30 @@ public:
unsigned PreallocatedID = 0,
unsigned Offset = 0);
+ /// \brief Retrieve the memory buffer associated with the given file.
+ const llvm::MemoryBuffer *getMemoryBufferForFile(const FileEntry *File);
+
+ /// \brief Override the contents of the given source file by providing an
+ /// already-allocated buffer.
+ ///
+ /// \param SourceFile the source file whose contents will be override.
+ ///
+ /// \param Buffer the memory buffer whose contents will be used as the
+ /// data in the given source file.
+ ///
+ /// \returns true if an error occurred, false otherwise.
+ bool overrideFileContents(const FileEntry *SourceFile,
+ const llvm::MemoryBuffer *Buffer);
+
//===--------------------------------------------------------------------===//
// FileID manipulation methods.
//===--------------------------------------------------------------------===//
- /// getBuffer - Return the buffer for the specified FileID.
- ///
- const llvm::MemoryBuffer *getBuffer(FileID FID) const {
- return getSLocEntry(FID).getFile().getContentCache()->getBuffer();
+ /// getBuffer - Return the buffer for the specified FileID. If there is an
+ /// error opening this buffer the first time, this manufactures a temporary
+ /// buffer and returns a non-empty error string.
+ const llvm::MemoryBuffer *getBuffer(FileID FID, std::string *Error = 0) const{
+ return getSLocEntry(FID).getFile().getContentCache()->getBuffer(Error);
}
/// getFileEntryForID - Returns the FileEntry record for the provided FileID.
@@ -669,12 +664,6 @@ public:
/// \returns true if LHS source location comes before RHS, false otherwise.
bool isBeforeInTranslationUnit(SourceLocation LHS, SourceLocation RHS) const;
- /// \brief Truncate the given file at the specified line/column.
- void truncateFileAt(const FileEntry *Entry, unsigned Line, unsigned Column);
-
- /// \brief Determine whether this file was truncated.
- bool isTruncatedFile(FileID FID) const;
-
// Iterators over FileInfos.
typedef llvm::DenseMap<const FileEntry*, SrcMgr::ContentCache*>
::const_iterator fileinfo_iterator;
diff --git a/include/clang/Basic/TokenKinds.def b/include/clang/Basic/TokenKinds.def
index 99422332a788..bb022f11759d 100644
--- a/include/clang/Basic/TokenKinds.def
+++ b/include/clang/Basic/TokenKinds.def
@@ -324,6 +324,8 @@ KEYWORD(__is_enum , KEYCXX)
KEYWORD(__is_pod , KEYCXX)
KEYWORD(__is_polymorphic , KEYCXX)
KEYWORD(__is_union , KEYCXX)
+// Tentative name - there's no implementation of std::is_literal_type yet.
+KEYWORD(__is_literal , KEYCXX)
// FIXME: Add MS's traits, too.
// Apple Extension.
diff --git a/include/clang/Basic/TypeTraits.h b/include/clang/Basic/TypeTraits.h
index 2a2eacc4caac..36b830069f86 100644
--- a/include/clang/Basic/TypeTraits.h
+++ b/include/clang/Basic/TypeTraits.h
@@ -32,7 +32,8 @@ namespace clang {
UTT_IsEnum,
UTT_IsPOD,
UTT_IsPolymorphic,
- UTT_IsUnion
+ UTT_IsUnion,
+ UTT_IsLiteral
};
}
diff --git a/include/clang/Driver/CC1Options.td b/include/clang/Driver/CC1Options.td
index b34fe0340a55..a9566f3f9d47 100644
--- a/include/clang/Driver/CC1Options.td
+++ b/include/clang/Driver/CC1Options.td
@@ -55,7 +55,7 @@ def analysis_CheckerCFRef : Flag<"-checker-cfref">,
def analysis_WarnSizeofPointer : Flag<"-warn-sizeof-pointer">,
HelpText<"Warn about unintended use of sizeof() on pointer expressions">;
def analysis_InlineCall : Flag<"-inline-call">,
- HelpText<"Experimental transfer function inling callees when its definition is available.">;
+ HelpText<"Experimental transfer function inlining callees when its definition is available.">;
def analyzer_store : Separate<"-analyzer-store">,
HelpText<"Source Code Analysis - Abstract Memory Store Models">;
@@ -73,6 +73,8 @@ def analyzer_output_EQ : Joined<"-analyzer-output=">,
def analyzer_opt_analyze_headers : Flag<"-analyzer-opt-analyze-headers">,
HelpText<"Force the static analyzer to analyze functions defined in header files">;
+def analyzer_opt_analyze_nested_blocks : Flag<"-analyzer-opt-analyze-nested-blocks">,
+ HelpText<"Analyze the definitions of blocks in addition to functions">;
def analyzer_display_progress : Flag<"-analyzer-display-progress">,
HelpText<"Emit verbose output about the analyzer's progress">;
def analyzer_experimental_checks : Flag<"-analyzer-experimental-checks">,
@@ -103,6 +105,8 @@ def disable_llvm_optzns : Flag<"-disable-llvm-optzns">,
def disable_red_zone : Flag<"-disable-red-zone">,
HelpText<"Do not emit code that uses the red zone.">;
def g : Flag<"-g">, HelpText<"Generate source level debug information">;
+def fcatch_undefined_behavior : Flag<"-fcatch-undefined-behavior">,
+ HelpText<"Generate runtime checks for undefined behavior.">;
def fno_common : Flag<"-fno-common">,
HelpText<"Compile common globals like normal definitions">;
def no_implicit_float : Flag<"-no-implicit-float">,
@@ -117,13 +121,13 @@ def mdebug_pass : Separate<"-mdebug-pass">,
HelpText<"Enable additional debug output">;
def mdisable_fp_elim : Flag<"-mdisable-fp-elim">,
HelpText<"Disable frame pointer elimination optimization">;
-def mfloat_abi : Flag<"-mfloat-abi">,
+def mfloat_abi : Separate<"-mfloat-abi">,
HelpText<"The float ABI to use">;
def mlimit_float_precision : Separate<"-mlimit-float-precision">,
HelpText<"Limit float precision to the given value">;
def mno_zero_initialized_in_bss : Flag<"-mno-zero-initialized-in-bss">,
HelpText<"Do not put zero initialized data in the BSS">;
-def msoft_float : Separate<"-msoft-float">,
+def msoft_float : Flag<"-msoft-float">,
HelpText<"Use software floating point">;
def mrelocation_model : Separate<"-mrelocation-model">,
HelpText<"The relocation model to use">;
@@ -149,7 +153,7 @@ def MP : Flag<"-MP">,
//===----------------------------------------------------------------------===//
def dump_build_information : Separate<"-dump-build-information">,
- MetaVarName<"filename">,
+ MetaVarName<"<filename>">,
HelpText<"output a dump of some build information to a file">;
def fno_show_column : Flag<"-fno-show-column">,
HelpText<"Do not include column number on diagnostics">;
@@ -172,7 +176,7 @@ def fdiagnostics_print_source_range_info : Flag<"-fdiagnostics-print-source-rang
HelpText<"Print source range spans in numeric form">;
def fdiagnostics_show_option : Flag<"-fdiagnostics-show-option">,
HelpText<"Print diagnostic name with mappable diagnostics">;
-def fmessage_length : Separate<"-fmessage-length">, MetaVarName<"N">,
+def fmessage_length : Separate<"-fmessage-length">, MetaVarName<"<N>">,
HelpText<"Format message diagnostics so that they fit within N columns or fewer, when possible.">;
def fcolor_diagnostics : Flag<"-fcolor-diagnostics">,
HelpText<"Use colors in diagnostics">;
@@ -185,28 +189,45 @@ def verify : Flag<"-verify">,
// Frontend Options
//===----------------------------------------------------------------------===//
+// This isn't normally used, it is just here so we can parse a
+// CompilerInvocation out of a driver-derived argument vector.
+def cc1 : Flag<"-cc1">;
+
def code_completion_at : Separate<"-code-completion-at">,
- MetaVarName<"file:line:column">,
+ MetaVarName<"<file>:<line>:<column>">,
HelpText<"Dump code-completion information at a location">;
+def remap_file : Separate<"-remap-file">,
+ MetaVarName<"<from>;<to>">,
+ HelpText<"Replace the contents of the <from> file with the contents of the <to> file">;
def code_completion_at_EQ : Joined<"-code-completion-at=">,
Alias<code_completion_at>;
def no_code_completion_debug_printer : Flag<"-no-code-completion-debug-printer">,
- HelpText<"Don't the \"debug\" code-completion print">;
+ HelpText<"Don't use the \"debug\" code-completion print">;
def code_completion_macros : Flag<"-code-completion-macros">,
HelpText<"Include macros in code-completion results">;
def disable_free : Flag<"-disable-free">,
HelpText<"Disable freeing of memory on exit">;
def empty_input_only : Flag<"-empty-input-only">,
HelpText<"Force running on an empty input file">;
+def help : Flag<"-help">,
+ HelpText<"Print this help text">;
+def _help : Flag<"--help">, Alias<help>;
def x : Separate<"-x">, HelpText<"Input language type">;
def cxx_inheritance_view : Separate<"-cxx-inheritance-view">,
- MetaVarName<"class name">,
+ MetaVarName<"<class name>">,
HelpText<"View C++ inheritance for a specified class">;
-def fixit_at : Separate<"-fixit-at">, MetaVarName<"source-location">,
+def fixit_at : Separate<"-fixit-at">, MetaVarName<"<source location>">,
HelpText<"Perform Fix-It modifications at the given source location">;
-def o : Separate<"-o">, MetaVarName<"path">, HelpText<"Specify output file">;
+def o : Separate<"-o">, MetaVarName<"<path>">, HelpText<"Specify output file">;
+def load : Separate<"-load">, MetaVarName<"<dsopath>">,
+ HelpText<"Load the named plugin (dynamic shared object)">;
def plugin : Separate<"-plugin">,
HelpText<"Use the named plugin action (use \"help\" to list available options)">;
+def resource_dir : Separate<"-resource-dir">,
+ HelpText<"The directory which holds the compiler resource files">;
+def version : Flag<"-version">,
+ HelpText<"Print the compiler version">;
+def _version : Flag<"--version">, Alias<version>;
def Action_Group : OptionGroup<"<action group>">;
let Group = Action_Group in {
@@ -313,7 +334,7 @@ def fno_signed_char : Flag<"-fno-signed-char">,
def fno_operator_names : Flag<"-fno-operator-names">,
HelpText<"Do not treat C++ operator name keywords as synonyms for operators">;
def fconstant_string_class : Separate<"-fconstant-string-class">,
- MetaVarName<"class name">,
+ MetaVarName<"<class name>">,
HelpText<"Specify the class to use for constant Objective-C string objects.">;
def fobjc_gc : Flag<"-fobjc-gc">,
HelpText<"Enable Objective-C garbage collection">;
@@ -326,7 +347,7 @@ def fobjc_nonfragile_abi : Flag<"-fobjc-nonfragile-abi">,
def ftrapv : Flag<"-ftrapv">,
HelpText<"Trap on integer overflow">;
def pic_level : Separate<"-pic-level">,
- HelpText<"-Value for __PIC__">;
+ HelpText<"Value for __PIC__">;
def pthread : Flag<"-pthread">,
HelpText<"Support POSIX threads in generated code">;
def fpascal_strings : Flag<"-fpascal-strings">,
@@ -356,23 +377,24 @@ def nostdinc : Flag<"-nostdinc">,
HelpText<"Disable standard #include directories">;
def nobuiltininc : Flag<"-nobuiltininc">,
HelpText<"Disable builtin #include directories">;
-def F : JoinedOrSeparate<"-F">, MetaVarName<"directory">,
+def F : JoinedOrSeparate<"-F">, MetaVarName<"<directory>">,
HelpText<"Add directory to framework include search path">;
-def I : JoinedOrSeparate<"-I">, MetaVarName<"directory">,
+def I : JoinedOrSeparate<"-I">, MetaVarName<"<directory>">,
HelpText<"Add directory to include search path">;
-def idirafter : Separate<"-idirafter">, MetaVarName<"directory">,
+def idirafter : JoinedOrSeparate<"-idirafter">, MetaVarName<"<directory>">,
HelpText<"Add directory to AFTER include search path">;
-def iquote : Separate<"-iquote">, MetaVarName<"directory">,
+def iquote : JoinedOrSeparate<"-iquote">, MetaVarName<"<directory>">,
HelpText<"Add directory to QUOTE include search path">;
-def isystem : Separate<"-isystem">, MetaVarName<"directory">,
+def isystem : JoinedOrSeparate<"-isystem">, MetaVarName<"<directory>">,
HelpText<"Add directory to SYSTEM include search path">;
-def iprefix : Separate<"-iprefix">, MetaVarName<"prefix">,
+def iprefix : JoinedOrSeparate<"-iprefix">, MetaVarName<"<prefix>">,
HelpText<"Set the -iwithprefix/-iwithprefixbefore prefix">;
-def iwithprefix : Separate<"-iwithprefix">, MetaVarName<"dir">,
+def iwithprefix : JoinedOrSeparate<"-iwithprefix">, MetaVarName<"<dir>">,
HelpText<"Set directory to SYSTEM include search path with prefix">;
-def iwithprefixbefore : Separate<"-iwithprefixbefore">, MetaVarName<"dir">,
+def iwithprefixbefore : JoinedOrSeparate<"-iwithprefixbefore">,
+ MetaVarName<"<dir>">,
HelpText<"Set directory to include search path with prefix">;
-def isysroot : Separate<"-isysroot">, MetaVarName<"dir">,
+def isysroot : JoinedOrSeparate<"-isysroot">, MetaVarName<"<dir>">,
HelpText<"Set the system root directory (usually /)">;
def v : Flag<"-v">, HelpText<"Enable verbose output">;
@@ -380,21 +402,21 @@ def v : Flag<"-v">, HelpText<"Enable verbose output">;
// Preprocessor Options
//===----------------------------------------------------------------------===//
-def D : JoinedOrSeparate<"-D">, MetaVarName<"macro">,
+def D : JoinedOrSeparate<"-D">, MetaVarName<"<macro>">,
HelpText<"Predefine the specified macro">;
-def include_ : Separate<"-include">, MetaVarName<"file">, EnumName<"include">,
+def include_ : JoinedOrSeparate<"-include">, MetaVarName<"<file>">, EnumName<"include">,
HelpText<"Include file before parsing">;
-def imacros : Separate<"-imacros">, MetaVarName<"file">,
+def imacros : JoinedOrSeparate<"-imacros">, MetaVarName<"<file>">,
HelpText<"Include macros from file before parsing">;
-def include_pch : Separate<"-include-pch">, MetaVarName<"file">,
+def include_pch : Separate<"-include-pch">, MetaVarName<"<file>">,
HelpText<"Include precompiled header file">;
-def include_pth : Separate<"-include-pth">, MetaVarName<"file">,
+def include_pth : Separate<"-include-pth">, MetaVarName<"<file>">,
HelpText<"Include file before parsing">;
-def token_cache : Separate<"-token-cache">, MetaVarName<"path">,
+def token_cache : Separate<"-token-cache">, MetaVarName<"<path>">,
HelpText<"Use specified token cache file">;
-def U : JoinedOrSeparate<"-U">, MetaVarName<"macro">,
+def U : JoinedOrSeparate<"-U">, MetaVarName<"<macro>">,
HelpText<"Undefine the specified macro">;
-def undef : Flag<"-undef">, MetaVarName<"macro">,
+def undef : Flag<"-undef">, MetaVarName<"<macro>">,
HelpText<"undef all system defines">;
//===----------------------------------------------------------------------===//
diff --git a/include/clang/Driver/Driver.h b/include/clang/Driver/Driver.h
index d3ab1153371a..8933619b2c25 100644
--- a/include/clang/Driver/Driver.h
+++ b/include/clang/Driver/Driver.h
@@ -15,6 +15,7 @@
#include "clang/Driver/Phases.h"
#include "clang/Driver/Util.h"
+#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/Triple.h"
#include "llvm/System/Path.h" // FIXME: Kill when CompilationInfo
// lands.
@@ -112,9 +113,9 @@ private:
std::list<std::string> ResultFiles;
public:
- Driver(const char *_Name, const char *_Dir,
- const char *_DefaultHostTriple,
- const char *_DefaultImageName,
+ Driver(llvm::StringRef _Name, llvm::StringRef _Dir,
+ llvm::StringRef _DefaultHostTriple,
+ llvm::StringRef _DefaultImageName,
bool IsProduction, Diagnostic &_Diags);
~Driver();
diff --git a/include/clang/Driver/Job.h b/include/clang/Driver/Job.h
index 906d73128b7d..74ca083417a6 100644
--- a/include/clang/Driver/Job.h
+++ b/include/clang/Driver/Job.h
@@ -22,7 +22,8 @@ using llvm::dyn_cast_or_null;
namespace clang {
namespace driver {
- class Command;
+class Command;
+class Tool;
class Job {
public:
@@ -55,6 +56,9 @@ class Command : public Job {
/// Source - The action which caused the creation of this job.
const Action &Source;
+ /// Tool - The tool which caused the creation of this job.
+ const Tool &Creator;
+
/// The executable to run.
const char *Executable;
@@ -63,12 +67,15 @@ class Command : public Job {
ArgStringList Arguments;
public:
- Command(const Action &_Source, const char *_Executable,
+ Command(const Action &_Source, const Tool &_Creator, const char *_Executable,
const ArgStringList &_Arguments);
/// getSource - Return the Action which caused the creation of this job.
const Action &getSource() const { return Source; }
+ /// getCreator - Return the Tool which caused the creation of this job.
+ const Tool &getCreator() const { return Creator; }
+
const char *getExecutable() const { return Executable; }
const ArgStringList &getArguments() const { return Arguments; }
diff --git a/include/clang/Driver/OptParser.td b/include/clang/Driver/OptParser.td
index f5b6980d8f6a..a9f4289fc86e 100644
--- a/include/clang/Driver/OptParser.td
+++ b/include/clang/Driver/OptParser.td
@@ -77,11 +77,17 @@ def RenderSeparate : OptionFlag;
// lines that use it.
def Unsupported : OptionFlag;
+// HelpHidden - The option should not be displayed in --help, even if it has
+// help text. Clients *can* use this in conjuction with the OptTable::PrintHelp
+// arguments to implement hidden help groups.
+def HelpHidden : OptionFlag;
+
// Define the option group class.
class OptionGroup<string name> {
string EnumName = ?; // Uses the def name if undefined.
string Name = name;
+ string HelpText = ?;
OptionGroup Group = ?;
}
diff --git a/include/clang/Driver/OptTable.h b/include/clang/Driver/OptTable.h
index faaeba69e2e6..edae75c9f057 100644
--- a/include/clang/Driver/OptTable.h
+++ b/include/clang/Driver/OptTable.h
@@ -13,17 +13,22 @@
#include "clang/Driver/OptSpecifier.h"
#include <cassert>
+namespace llvm {
+ class raw_ostream;
+}
+
namespace clang {
namespace driver {
namespace options {
enum DriverFlag {
DriverOption = (1 << 0),
- LinkerInput = (1 << 1),
- NoArgumentUnused = (1 << 2),
- RenderAsInput = (1 << 3),
- RenderJoined = (1 << 4),
- RenderSeparate = (1 << 5),
- Unsupported = (1 << 6)
+ HelpHidden = (1 << 1),
+ LinkerInput = (1 << 2),
+ NoArgumentUnused = (1 << 3),
+ RenderAsInput = (1 << 4),
+ RenderJoined = (1 << 5),
+ RenderSeparate = (1 << 6),
+ Unsupported = (1 << 7)
};
}
@@ -113,6 +118,17 @@ namespace options {
return getInfo(id).Kind;
}
+ /// getOptionGroupID - Get the group id for the given option.
+ unsigned getOptionGroupID(OptSpecifier id) const {
+ return getInfo(id).GroupID;
+ }
+
+ /// isOptionHelpHidden - Should the help for the given option be hidden by
+ /// default.
+ bool isOptionHelpHidden(OptSpecifier id) const {
+ return getInfo(id).Flags & options::HelpHidden;
+ }
+
/// getOptionHelpText - Get the help text to use to describe this option.
const char *getOptionHelpText(OptSpecifier id) const {
return getInfo(id).HelpText;
@@ -156,6 +172,15 @@ namespace options {
const char **ArgEnd,
unsigned &MissingArgIndex,
unsigned &MissingArgCount) const;
+
+ /// PrintHelp - Render the help text for an option table.
+ ///
+ /// \param OS - The stream to write the help text to.
+ /// \param Name - The name to use in the usage line.
+ /// \param Title - The title to use in the usage line.
+ /// \param ShowHidden - Whether help-hidden arguments should be shown.
+ void PrintHelp(llvm::raw_ostream &OS, const char *Name,
+ const char *Title, bool ShowHidden = false) const;
};
}
}
diff --git a/include/clang/Driver/Options.td b/include/clang/Driver/Options.td
index ace1a3c16add..3592fc946846 100644
--- a/include/clang/Driver/Options.td
+++ b/include/clang/Driver/Options.td
@@ -61,6 +61,55 @@ def clang_ignored_m_Group : OptionGroup<"<clang ignored m group>">,
// = => _EQ
// C++ => CXX
+// Developer Driver Options
+
+def ccc_Group : OptionGroup<"<clang internal options>">;
+def ccc_driver_Group : OptionGroup<"<clang driver internal options>">,
+ Group<ccc_Group>, HelpText<"DRIVER OPTIONS">;
+def ccc_debug_Group : OptionGroup<"<clang debug/development internal options>">,
+ Group<ccc_Group>, HelpText<"DEBUG/DEVELOPMENT OPTIONS">;
+
+class CCCDriverOpt : Group<ccc_driver_Group>, Flags<[DriverOption, HelpHidden]>;
+def ccc_cxx : Flag<"-ccc-cxx">, CCCDriverOpt,
+ HelpText<"Act as a C++ driver">;
+def ccc_echo : Flag<"-ccc-echo">, CCCDriverOpt,
+ HelpText<"Echo commands before running them">;
+def ccc_gcc_name : Separate<"-ccc-gcc-name">, CCCDriverOpt,
+ HelpText<"Name for native GCC compiler">,
+ MetaVarName<"<gcc-path>">;
+def ccc_clang_cxx : Flag<"-ccc-clang-cxx">, CCCDriverOpt,
+ HelpText<"Enable the clang compiler for C++">;
+def ccc_no_clang_cxx : Flag<"-ccc-no-clang-cxx">, CCCDriverOpt,
+ HelpText<"Disable the clang compiler for C++">;
+def ccc_no_clang : Flag<"-ccc-no-clang">, CCCDriverOpt,
+ HelpText<"Disable the clang compiler">;
+def ccc_no_clang_cpp : Flag<"-ccc-no-clang-cpp">, CCCDriverOpt,
+ HelpText<"Disable the clang preprocessor">;
+def ccc_clang_archs : Separate<"-ccc-clang-archs">, CCCDriverOpt,
+ HelpText<"Comma separate list of architectures to use the clang compiler for">,
+ MetaVarName<"<arch-list>">;
+def ccc_pch_is_pch : Flag<"-ccc-pch-is-pch">, CCCDriverOpt,
+ HelpText<"Use lazy PCH for precompiled headers">;
+def ccc_pch_is_pth : Flag<"-ccc-pch-is-pth">, CCCDriverOpt,
+ HelpText<"Use pretokenized headers for precompiled headers">;
+
+class CCCDebugOpt : Group<ccc_debug_Group>, Flags<[DriverOption, HelpHidden]>;
+def ccc_host_triple : Separate<"-ccc-host-triple">, CCCDebugOpt,
+ HelpText<"Simulate running on the given target">;
+def ccc_install_dir : Separate<"-ccc-install-dir">, CCCDebugOpt,
+ HelpText<"Simulate installation in the given directory">;
+def ccc_print_options : Flag<"-ccc-print-options">, CCCDebugOpt,
+ HelpText<"Dump parsed command line arguments">;
+def ccc_print_phases : Flag<"-ccc-print-phases">, CCCDebugOpt,
+ HelpText<"Dump list of actions to perform">;
+def ccc_print_bindings : Flag<"-ccc-print-bindings">, CCCDebugOpt,
+ HelpText<"Show bindings of tools to actions">;
+
+// Make sure all other -ccc- options are rejected.
+def ccc_ : Joined<"-ccc-">, Group<ccc_Group>, Flags<[Unsupported]>;
+
+// Standard Options
+
def _HASH_HASH_HASH : Flag<"-###">, Flags<[DriverOption]>,
HelpText<"Print the commands to run for this compilation">;
def A : JoinedOrSeparate<"-A">;
@@ -187,6 +236,8 @@ def fbootclasspath_EQ : Joined<"-fbootclasspath=">, Group<f_Group>;
def fbuiltin_strcat : Flag<"-fbuiltin-strcat">, Group<f_Group>;
def fbuiltin_strcpy : Flag<"-fbuiltin-strcpy">, Group<f_Group>;
def fbuiltin : Flag<"-fbuiltin">, Group<f_Group>;
+def fcatch_undefined_behavior : Flag<"-fcatch-undefined-behavior">,
+ Group<f_Group>, HelpText<"Generate runtime checks for undefined behavior.">;
def fclasspath_EQ : Joined<"-fclasspath=">, Group<f_Group>;
def fcolor_diagnostics : Flag<"-fcolor-diagnostics">, Group<f_Group>;
def fcommon : Flag<"-fcommon">, Group<f_Group>;
@@ -277,6 +328,9 @@ def fprofile_arcs : Flag<"-fprofile-arcs">, Group<f_Group>;
def fprofile_generate : Flag<"-fprofile-generate">, Group<f_Group>;
def framework : Separate<"-framework">, Flags<[LinkerInput]>;
def frtti : Flag<"-frtti">, Group<f_Group>;
+def fsched_interblock : Flag<"-fsched-interblock">, Group<clang_ignored_f_Group>;
+def fshort_enums : Flag<"-fshort-enums">, Group<clang_ignored_f_Group>;
+def freorder_blocks : Flag<"-freorder-blocks">, Group<clang_ignored_f_Group>;
def fshort_wchar : Flag<"-fshort-wchar">, Group<f_Group>;
def fshow_source_location : Flag<"-fshow-source-location">, Group<f_Group>;
def fsigned_bitfields : Flag<"-fsigned-bitfields">, Group<f_Group>;
@@ -315,7 +369,7 @@ def init : Separate<"-init">;
def install__name : Separate<"-install_name">;
def iprefix : JoinedOrSeparate<"-iprefix">, Group<clang_i_Group>;
def iquote : JoinedOrSeparate<"-iquote">, Group<clang_i_Group>;
-def isysroot : JoinedOrSeparate<"-isysroot">, Group<i_Group>;
+def isysroot : JoinedOrSeparate<"-isysroot">, Group<clang_i_Group>;
def isystem : JoinedOrSeparate<"-isystem">, Group<clang_i_Group>;
def iwithprefixbefore : JoinedOrSeparate<"-iwithprefixbefore">, Group<clang_i_Group>;
def iwithprefix : JoinedOrSeparate<"-iwithprefix">, Group<clang_i_Group>;
@@ -373,6 +427,8 @@ def multiply__defined : Separate<"-multiply_defined">;
def mwarn_nonportable_cfstrings : Flag<"-mwarn-nonportable-cfstrings">, Group<m_Group>;
def m_Separate : Separate<"-m">, Group<m_Group>;
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_cpp : Flag<"-no-integrated-cpp">, Flags<[DriverOption]>;
def no__dead__strip__inits__and__terms : Flag<"-no_dead_strip_inits_and_terms">;
diff --git a/include/clang/Frontend/ASTConsumers.h b/include/clang/Frontend/ASTConsumers.h
index 26efa9745600..20bf83ee0456 100644
--- a/include/clang/Frontend/ASTConsumers.h
+++ b/include/clang/Frontend/ASTConsumers.h
@@ -94,9 +94,9 @@ ASTConsumer *CreateHTMLPrinter(llvm::raw_ostream *OS, Preprocessor &PP,
bool SyntaxHighlight = true,
bool HighlightMacros = true);
-// PCH generator: generates a precompiled header file; this file can be
-// used later with the PCHReader (clang-cc option -include-pch)
-// to speed up compile times.
+// PCH generator: generates a precompiled header file; this file can be used
+// later with the PCHReader (clang -cc1 option -include-pch) to speed up compile
+// times.
ASTConsumer *CreatePCHGenerator(const Preprocessor &PP,
llvm::raw_ostream *OS,
const char *isysroot = 0);
diff --git a/include/clang/Frontend/ASTUnit.h b/include/clang/Frontend/ASTUnit.h
index 04dc5ed8cc56..f18972ab3445 100644
--- a/include/clang/Frontend/ASTUnit.h
+++ b/include/clang/Frontend/ASTUnit.h
@@ -16,10 +16,11 @@
#include "clang/Basic/SourceManager.h"
#include "llvm/ADT/OwningPtr.h"
-#include "clang/Frontend/TextDiagnosticBuffer.h"
#include "clang/Basic/FileManager.h"
#include "clang/Index/ASTLocation.h"
#include <string>
+#include <vector>
+#include <cassert>
namespace clang {
class ASTContext;
@@ -32,14 +33,12 @@ class HeaderSearch;
class Preprocessor;
class SourceManager;
class TargetInfo;
-class TextDiagnosticBuffer;
using namespace idx;
/// \brief Utility class for loading a ASTContext from a PCH file.
///
class ASTUnit {
- Diagnostic Diags;
FileManager FileMgr;
SourceManager SourceMgr;
@@ -48,22 +47,39 @@ class ASTUnit {
llvm::OwningPtr<Preprocessor> PP;
llvm::OwningPtr<ASTContext> Ctx;
bool tempFile;
-
+
// 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.
bool OnlyLocalDecls;
-
+
+ /// Track whether the main file was loaded from an AST or not.
+ bool MainFileIsAST;
+
+ /// Track the top-level decls which appeared in an ASTUnit which was loaded
+ /// from a source file.
+ //
+ // FIXME: This is just an optimization hack to avoid deserializing large parts
+ // of a PCH file when using the Index library on an ASTUnit loaded from
+ // source. In the long term we should make the Index library use efficient and
+ // more scalable search mechanisms.
+ std::vector<Decl*> TopLevelDecls;
+
+ /// The name of the original source file used to generate this ASTUnit.
+ std::string OriginalSourceFile;
+
// Critical optimization when using clang_getCursor().
ASTLocation LastLoc;
-
+
ASTUnit(const ASTUnit&); // DO NOT IMPLEMENT
ASTUnit &operator=(const ASTUnit &); // DO NOT IMPLEMENT
public:
- ASTUnit(DiagnosticClient *diagClient = NULL);
+ ASTUnit(bool MainFileIsAST);
~ASTUnit();
+ bool isMainFileAST() const { return MainFileIsAST; }
+
const SourceManager &getSourceManager() const { return SourceMgr; }
SourceManager &getSourceManager() { return SourceMgr; }
@@ -73,37 +89,38 @@ public:
const ASTContext &getASTContext() const { return *Ctx.get(); }
ASTContext &getASTContext() { return *Ctx.get(); }
- const Diagnostic &getDiagnostic() const { return Diags; }
- Diagnostic &getDiagnostic() { return Diags; }
-
const FileManager &getFileManager() const { return FileMgr; }
FileManager &getFileManager() { return FileMgr; }
-
+
const std::string &getOriginalSourceFileName();
const std::string &getPCHFileName();
void unlinkTemporaryFile() { tempFile = true; }
-
+
bool getOnlyLocalDecls() const { return OnlyLocalDecls; }
-
+
void setLastASTLocation(ASTLocation ALoc) { LastLoc = ALoc; }
ASTLocation getLastASTLocation() const { return LastLoc; }
-
+
+ std::vector<Decl*> &getTopLevelDecls() {
+ assert(!isMainFileAST() && "Invalid call for AST based ASTUnit!");
+ return TopLevelDecls;
+ }
+ const std::vector<Decl*> &getTopLevelDecls() const {
+ assert(!isMainFileAST() && "Invalid call for AST based ASTUnit!");
+ return TopLevelDecls;
+ }
+
/// \brief Create a ASTUnit from a PCH file.
///
/// \param Filename - The PCH file to load.
///
- /// \param DiagClient - The diagnostics client to use. Specify NULL
- /// to use a default client that emits warnings/errors to standard error.
- /// The ASTUnit objects takes ownership of this object.
- ///
- /// \param ErrMsg - Error message to report if the PCH file could not be
- /// loaded.
+ /// \param Diags - The diagnostics engine to use for reporting errors; its
+ /// lifetime is expected to extend past that of the returned ASTUnit.
///
/// \returns - The initialized ASTUnit or null if the PCH failed to load.
static ASTUnit *LoadFromPCHFile(const std::string &Filename,
- std::string *ErrMsg = 0,
- DiagnosticClient *DiagClient = NULL,
+ Diagnostic &Diags,
bool OnlyLocalDecls = false,
bool UseBumpAllocator = false);
@@ -113,15 +130,35 @@ public:
/// \param CI - The compiler invocation to use; it must have exactly one input
/// source file.
///
- /// \param Diags - The diagnostics engine to use for reporting errors.
+ /// \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,
Diagnostic &Diags,
- bool OnlyLocalDecls = false,
- bool UseBumpAllocator = false);
+ bool OnlyLocalDecls = false);
+ /// LoadFromCommandLine - Create an ASTUnit from a vector of command line
+ /// arguments, which must specify exactly one source file.
+ ///
+ /// \param ArgBegin - The beginning of the argument vector.
+ ///
+ /// \param ArgEnd - The end of the argument vector.
+ ///
+ /// \param Diags - The diagnostics engine to use for reporting errors; its
+ /// lifetime is expected to extend past that of the returned ASTUnit.
+ ///
+ /// \param ResourceFilesPath - The path to the compiler resource files.
+ //
+ // FIXME: Move OnlyLocalDecls, UseBumpAllocator to setters on the ASTUnit, we
+ // shouldn't need to specify them at construction time.
+ static ASTUnit *LoadFromCommandLine(const char **ArgBegin,
+ const char **ArgEnd,
+ Diagnostic &Diags,
+ llvm::StringRef ResourceFilesPath,
+ bool OnlyLocalDecls = false,
+ bool UseBumpAllocator = false);
};
} // namespace clang
diff --git a/include/clang/Frontend/AnalysisConsumer.h b/include/clang/Frontend/AnalysisConsumer.h
index 24fed6e76ac1..f55e5dc04055 100644
--- a/include/clang/Frontend/AnalysisConsumer.h
+++ b/include/clang/Frontend/AnalysisConsumer.h
@@ -62,6 +62,7 @@ public:
std::string AnalyzeSpecificFunction;
unsigned AnalyzeAll : 1;
unsigned AnalyzerDisplayProgress : 1;
+ unsigned AnalyzeNestedBlocks : 1;
unsigned EagerlyAssume : 1;
unsigned PurgeDead : 1;
unsigned TrimGraph : 1;
@@ -76,6 +77,7 @@ public:
AnalysisDiagOpt = PD_HTML;
AnalyzeAll = 0;
AnalyzerDisplayProgress = 0;
+ AnalyzeNestedBlocks = 0;
EagerlyAssume = 0;
PurgeDead = 1;
TrimGraph = 0;
diff --git a/include/clang/Frontend/CompilerInstance.h b/include/clang/Frontend/CompilerInstance.h
index d7e7d991f379..18ec429db7e8 100644
--- a/include/clang/Frontend/CompilerInstance.h
+++ b/include/clang/Frontend/CompilerInstance.h
@@ -222,7 +222,7 @@ public:
void setDiagnostics(Diagnostic *Value);
DiagnosticClient &getDiagnosticClient() const {
- assert(Target && "Compiler instance has no diagnostic client!");
+ assert(DiagClient && "Compiler instance has no diagnostic client!");
return *DiagClient;
}
@@ -419,9 +419,13 @@ public:
/// logging information.
///
/// Note that this creates an unowned DiagnosticClient, if using directly the
- /// caller is responsible for releaseing the returned Diagnostic's client
+ /// caller is responsible for releasing the returned Diagnostic's client
/// eventually.
///
+ /// \param Opts - The diagnostic options; note that the created text
+ /// diagnostic object contains a reference to these options and its lifetime
+ /// must extend past that of the diagnostic engine.
+ ///
/// \return The new object on success, or null on failure.
static Diagnostic *createDiagnostics(const DiagnosticOptions &Opts,
int Argc, char **Argv);
@@ -482,12 +486,16 @@ public:
/// Create the default output file (from the invocation's options) and add it
/// to the list of tracked output files.
+ ///
+ /// \return - Null on error.
llvm::raw_fd_ostream *
createDefaultOutputFile(bool Binary = true, llvm::StringRef BaseInput = "",
llvm::StringRef Extension = "");
/// Create a new output file and add it to the list of tracked output files,
/// optionally deriving the output path name.
+ ///
+ /// \return - Null on error.
llvm::raw_fd_ostream *
createOutputFile(llvm::StringRef OutputPath, bool Binary = true,
llvm::StringRef BaseInput = "",
diff --git a/include/clang/Frontend/CompilerInvocation.h b/include/clang/Frontend/CompilerInvocation.h
index e7c51aabba59..f5a9053ceb64 100644
--- a/include/clang/Frontend/CompilerInvocation.h
+++ b/include/clang/Frontend/CompilerInvocation.h
@@ -82,15 +82,19 @@ public:
/// \param Res [out] - The resulting invocation.
/// \param ArgBegin - The first element in the argument vector.
/// \param ArgEnd - The last element in the argument vector.
+ /// \param Diags - The diagnostic engine to use for errors.
+ static void CreateFromArgs(CompilerInvocation &Res, const char **ArgBegin,
+ const char **ArgEnd, Diagnostic &Diags);
+
+ /// GetBuiltinIncludePath - Get the directory where the compiler headers
+ /// reside, relative to the compiler binary (found by the passed in
+ /// arguments).
+ ///
/// \param Argv0 - The program path (from argv[0]), for finding the builtin
/// compiler path.
/// \param MainAddr - The address of main (or some other function in the main
/// executable), for finding the builtin compiler path.
- /// \param Diags - The diagnostic engine to use for errors.
- static void CreateFromArgs(CompilerInvocation &Res, const char **ArgBegin,
- const char **ArgEnd, const char *Argv0,
- void *MainAddr,
- Diagnostic &Diags);
+ static std::string GetResourcesPath(const char *Argv0, void *MainAddr);
/// toArgs - Convert the CompilerInvocation to a list of strings suitable for
/// passing to CreateFromArgs.
diff --git a/include/clang/Frontend/FrontendOptions.h b/include/clang/Frontend/FrontendOptions.h
index c1ec8e70f1c6..36fea7f71337 100644
--- a/include/clang/Frontend/FrontendOptions.h
+++ b/include/clang/Frontend/FrontendOptions.h
@@ -77,12 +77,14 @@ public:
unsigned RelocatablePCH : 1; ///< When generating PCH files,
/// instruct the PCH writer to create
/// relocatable PCH files.
+ unsigned ShowHelp : 1; ///< Show the -help text.
unsigned ShowMacrosInCodeCompletion : 1; ///< Show macros in code completion
/// results.
unsigned ShowStats : 1; ///< Show frontend performance
/// metrics and statistics.
unsigned ShowTimers : 1; ///< Show timers for individual
/// actions.
+ unsigned ShowVersion : 1; ///< Show the -version text.
/// The input files and their types.
std::vector<std::pair<InputKind, std::string> > Inputs;
@@ -105,6 +107,9 @@ public:
/// The name of the action to run when using a plugin action.
std::string ActionName;
+ /// The list of plugins to load.
+ std::vector<std::string> Plugins;
+
public:
FrontendOptions() {
DebugCodeCompletionPrinter = 1;
@@ -113,9 +118,11 @@ public:
ProgramAction = frontend::ParseSyntaxOnly;
ActionName = "";
RelocatablePCH = 0;
+ ShowHelp = 0;
ShowMacrosInCodeCompletion = 0;
ShowStats = 0;
ShowTimers = 0;
+ ShowVersion = 0;
}
/// getInputKindForExtension - Return the appropriate input kind for a file
diff --git a/include/clang/Frontend/HeaderSearchOptions.h b/include/clang/Frontend/HeaderSearchOptions.h
index 67129775ac8d..690408547c0d 100644
--- a/include/clang/Frontend/HeaderSearchOptions.h
+++ b/include/clang/Frontend/HeaderSearchOptions.h
@@ -61,9 +61,12 @@ public:
std::string CXXEnvIncPath;
std::string ObjCXXEnvIncPath;
- /// If non-empty, the path to the compiler builtin include directory, which
- /// will be searched following the user and environment includes.
- std::string BuiltinIncludePath;
+ /// The directory which holds the compiler resource files (builtin includes,
+ /// etc.).
+ std::string ResourceDir;
+
+ /// Include the compiler builtin includes.
+ unsigned UseBuiltinIncludes : 1;
/// Include the system standard include search directories.
unsigned UseStandardIncludes : 1;
@@ -73,7 +76,8 @@ public:
public:
HeaderSearchOptions(llvm::StringRef _Sysroot = "/")
- : Sysroot(_Sysroot), UseStandardIncludes(true), Verbose(false) {}
+ : Sysroot(_Sysroot), UseBuiltinIncludes(true),
+ UseStandardIncludes(true), Verbose(false) {}
/// AddPath - Add the \arg Path path to the specified \arg Group list.
void AddPath(llvm::StringRef Path, frontend::IncludeDirGroup Group,
diff --git a/include/clang/Frontend/PCHBitCodes.h b/include/clang/Frontend/PCHBitCodes.h
index 98463c308e51..c8c49c83f940 100644
--- a/include/clang/Frontend/PCHBitCodes.h
+++ b/include/clang/Frontend/PCHBitCodes.h
@@ -404,7 +404,9 @@ namespace clang {
/// \brief An ElaboratedType record.
TYPE_ELABORATED = 24,
/// \brief A SubstTemplateTypeParmType record.
- TYPE_SUBST_TEMPLATE_TYPE_PARM = 25
+ TYPE_SUBST_TEMPLATE_TYPE_PARM = 25,
+ /// \brief An UnresolvedUsingType record.
+ TYPE_UNRESOLVED_USING = 26
};
/// \brief The type IDs for special types constructed by semantic
diff --git a/include/clang/Frontend/PCHReader.h b/include/clang/Frontend/PCHReader.h
index 85861fab4a22..7e2c65690fd6 100644
--- a/include/clang/Frontend/PCHReader.h
+++ b/include/clang/Frontend/PCHReader.h
@@ -530,7 +530,8 @@ public:
/// \brief Retrieve the name of the original source file name
/// directly from the PCH file, without actually loading the PCH
/// file.
- static std::string getOriginalSourceFile(const std::string &PCHFileName);
+ static std::string getOriginalSourceFile(const std::string &PCHFileName,
+ Diagnostic &Diags);
/// \brief Returns the suggested contents of the predefines buffer,
/// which contains a (typically-empty) subset of the predefines
@@ -552,7 +553,7 @@ public:
const RecordData &Record, unsigned &Idx);
/// \brief Reads a declarator info from the given record.
- virtual DeclaratorInfo *GetDeclaratorInfo(const RecordData &Record,
+ virtual TypeSourceInfo *GetTypeSourceInfo(const RecordData &Record,
unsigned &Idx);
/// \brief Resolve a type ID into a type, potentially building a new
@@ -625,6 +626,9 @@ public:
/// tree.
virtual void InitializeSema(Sema &S);
+ /// \brief Inform the semantic consumer that Sema is no longer available.
+ virtual void ForgetSema() { SemaObj = 0; }
+
/// \brief Retrieve the IdentifierInfo for the named identifier.
///
/// This routine builds a new IdentifierInfo for the given identifier. If any
diff --git a/include/clang/Frontend/PCHWriter.h b/include/clang/Frontend/PCHWriter.h
index b520f4be1d31..212130e2ea62 100644
--- a/include/clang/Frontend/PCHWriter.h
+++ b/include/clang/Frontend/PCHWriter.h
@@ -44,7 +44,6 @@ class TargetInfo;
/// DenseMap. This uses the standard pointer hash function.
struct UnsafeQualTypeDenseMapInfo {
static inline bool isEqual(QualType A, QualType B) { return A == B; }
- static inline bool isPod() { return true; }
static inline QualType getEmptyKey() {
return QualType::getFromOpaquePtr((void*) 1);
}
@@ -274,7 +273,7 @@ public:
void AddTypeRef(QualType T, RecordData &Record);
/// \brief Emits a reference to a declarator info.
- void AddDeclaratorInfo(DeclaratorInfo *DInfo, RecordData &Record);
+ void AddTypeSourceInfo(TypeSourceInfo *TInfo, RecordData &Record);
/// \brief Emits a template argument location.
void AddTemplateArgumentLoc(const TemplateArgumentLoc &Arg,
diff --git a/include/clang/Frontend/PreprocessorOptions.h b/include/clang/Frontend/PreprocessorOptions.h
index f0c1d3c2c38d..c43a1feb8c05 100644
--- a/include/clang/Frontend/PreprocessorOptions.h
+++ b/include/clang/Frontend/PreprocessorOptions.h
@@ -13,6 +13,7 @@
#include "llvm/ADT/StringRef.h"
#include <cassert>
#include <string>
+#include <utility>
#include <vector>
namespace clang {
@@ -41,6 +42,21 @@ public:
/// If given, a PTH cache file to use for speeding up header parsing.
std::string TokenCache;
+ /// \brief The set of file remappings, which take existing files on
+ /// the system (the first part of each pair) and gives them the
+ /// contents of other files on the system (the second part of each
+ /// pair).
+ std::vector<std::pair<std::string, std::string> > RemappedFiles;
+
+ typedef std::vector<std::pair<std::string, std::string> >::const_iterator
+ remapped_file_iterator;
+ remapped_file_iterator remapped_file_begin() const {
+ return RemappedFiles.begin();
+ }
+ remapped_file_iterator remapped_file_end() const {
+ return RemappedFiles.end();
+ }
+
public:
PreprocessorOptions() : UsePredefines(true) {}
@@ -50,6 +66,9 @@ public:
void addMacroUndef(llvm::StringRef Name) {
Macros.push_back(std::make_pair(Name, true));
}
+ void addRemappedFile(llvm::StringRef From, llvm::StringRef To) {
+ RemappedFiles.push_back(std::make_pair(From, To));
+ }
};
} // end namespace clang
diff --git a/include/clang/Analysis/CallGraph.h b/include/clang/Index/CallGraph.h
index 5edfe6fea8db..5edfe6fea8db 100644
--- a/include/clang/Analysis/CallGraph.h
+++ b/include/clang/Index/CallGraph.h
diff --git a/include/clang/Index/Entity.h b/include/clang/Index/Entity.h
index 4533a1a0ac08..c2aab62e23f2 100644
--- a/include/clang/Index/Entity.h
+++ b/include/clang/Index/Entity.h
@@ -134,9 +134,10 @@ struct DenseMapInfo<clang::idx::Entity> {
isEqual(clang::idx::Entity LHS, clang::idx::Entity RHS) {
return LHS == RHS;
}
-
- static inline bool isPod() { return true; }
};
+
+template <>
+struct isPodLike<clang::idx::Entity> { static const bool value = true; };
} // end namespace llvm
diff --git a/include/clang/Index/GlobalSelector.h b/include/clang/Index/GlobalSelector.h
index 51f98267f356..9cd83a8595b9 100644
--- a/include/clang/Index/GlobalSelector.h
+++ b/include/clang/Index/GlobalSelector.h
@@ -90,9 +90,10 @@ struct DenseMapInfo<clang::idx::GlobalSelector> {
isEqual(clang::idx::GlobalSelector LHS, clang::idx::GlobalSelector RHS) {
return LHS == RHS;
}
-
- static inline bool isPod() { return true; }
};
+
+template <>
+struct isPodLike<clang::idx::GlobalSelector> { static const bool value = true;};
} // end namespace llvm
diff --git a/include/clang/Lex/Lexer.h b/include/clang/Lex/Lexer.h
index 52bf194883df..fc65b1fc5449 100644
--- a/include/clang/Lex/Lexer.h
+++ b/include/clang/Lex/Lexer.h
@@ -38,8 +38,8 @@ class Lexer : public PreprocessorLexer {
const char *BufferEnd; // End of the buffer.
SourceLocation FileLoc; // Location for start of file.
LangOptions Features; // Features enabled by this language (cache).
- bool Is_PragmaLexer; // True if lexer for _Pragma handling.
- bool IsEofCodeCompletion; // True if EOF is treated as a code-completion.
+ bool Is_PragmaLexer : 1; // True if lexer for _Pragma handling.
+ bool IsInConflictMarker : 1; // True if in a VCS conflict marker '<<<<<<<'
//===--------------------------------------------------------------------===//
// Context-specific lexing flags set by the preprocessor.
@@ -180,15 +180,6 @@ public:
ExtendedTokenMode = Mode ? 1 : 0;
}
- /// \brief Specify that end-of-file is to be considered a code-completion
- /// token.
- ///
- /// When in this mode, the end-of-file token will be immediately preceded
- /// by a code-completion token.
- void SetEofIsCodeCompletion(bool Val = true) {
- IsEofCodeCompletion = Val;
- }
-
const char *getBufferStart() const { return BufferStart; }
/// ReadToEndOfLine - Read the rest of the current preprocessor line as an
@@ -379,6 +370,9 @@ private:
bool SkipBCPLComment (Token &Result, const char *CurPtr);
bool SkipBlockComment (Token &Result, const char *CurPtr);
bool SaveBCPLComment (Token &Result, const char *CurPtr);
+
+ bool IsStartOfConflictMarker(const char *CurPtr);
+ bool HandleEndOfConflictMarker(const char *CurPtr);
};
diff --git a/include/clang/Lex/Preprocessor.h b/include/clang/Lex/Preprocessor.h
index edd34b718969..7c838ff86243 100644
--- a/include/clang/Lex/Preprocessor.h
+++ b/include/clang/Lex/Preprocessor.h
@@ -91,12 +91,14 @@ class Preprocessor {
bool KeepMacroComments : 1;
// State that changes while the preprocessor runs:
- bool DisableMacroExpansion : 1; // True if macro expansion is disabled.
bool InMacroArgs : 1; // True if parsing fn macro invocation args.
/// Whether the preprocessor owns the header search object.
bool OwnsHeaderSearch : 1;
+ /// DisableMacroExpansion - True if macro expansion is disabled.
+ bool DisableMacroExpansion : 1;
+
/// Identifiers - This is mapping/lookup information for all identifiers in
/// the program, including program keywords.
mutable IdentifierTable Identifiers;
@@ -121,6 +123,9 @@ class Preprocessor {
/// with this preprocessor.
std::vector<CommentHandler *> CommentHandlers;
+ /// \brief The file that we're performing code-completion for, if any.
+ const FileEntry *CodeCompletionFile;
+
/// CurLexer - This is the current top of the stack that we're lexing from if
/// not expanding a macro and we are lexing directly from source code.
/// Only one of CurLexer, CurPTHLexer, or CurTokenLexer will be non-null.
@@ -134,7 +139,7 @@ class Preprocessor {
/// CurPPLexer - This is the current top of the stack what we're lexing from
/// if not expanding a macro. This is an alias for either CurLexer or
/// CurPTHLexer.
- PreprocessorLexer* CurPPLexer;
+ PreprocessorLexer *CurPPLexer;
/// CurLookup - The DirectoryLookup structure used to find the current
/// FileEntry, if CurLexer is non-null and if applicable. This allows us to
@@ -171,8 +176,14 @@ class Preprocessor {
llvm::DenseMap<IdentifierInfo*, MacroInfo*> Macros;
/// MICache - A "freelist" of MacroInfo objects that can be reused for quick
- /// allocation.
+ /// allocation.
+ /// FIXME: why not use a singly linked list?
std::vector<MacroInfo*> MICache;
+
+ /// MacroArgCache - This is a "freelist" of MacroArg objects that can be
+ /// reused for quick allocation.
+ MacroArgs *MacroArgCache;
+ friend class MacroArgs;
// Various statistics we track for performance analysis.
unsigned NumDirectives, NumIncluded, NumDefined, NumUndefined, NumPragma;
@@ -330,8 +341,9 @@ public:
/// EnterSourceFile - Add a source file to the top of the include stack and
/// start lexing tokens from it instead of the current buffer. Return true
- /// on failure.
- bool EnterSourceFile(FileID CurFileID, const DirectoryLookup *Dir);
+ /// and fill in ErrorStr with the error information on failure.
+ bool EnterSourceFile(FileID CurFileID, const DirectoryLookup *Dir,
+ std::string &ErrorStr);
/// EnterMacro - Add a Macro to the top of the include stack and start lexing
/// tokens from it instead of the current buffer. Args specifies the
@@ -484,6 +496,27 @@ public:
CachedTokens[CachedLexPos-1] = Tok;
}
+ /// \brief Specify the point at which code-completion will be performed.
+ ///
+ /// \param File the file in which code completion should occur. If
+ /// this file is included multiple times, code-completion will
+ /// perform completion the first time it is included. If NULL, this
+ /// function clears out the code-completion point.
+ ///
+ /// \param Line the line at which code completion should occur
+ /// (1-based).
+ ///
+ /// \param Column the column at which code completion should occur
+ /// (1-based).
+ ///
+ /// \returns true if an error occurred, false otherwise.
+ bool SetCodeCompletionPoint(const FileEntry *File,
+ unsigned Line, unsigned Column);
+
+ /// \brief Determine if this source location refers into the file
+ /// for which we are performing code completion.
+ bool isCodeCompletionFile(SourceLocation FileLoc) const;
+
/// Diag - Forwarding function for diagnostics. This emits a diagnostic at
/// the specified Token's location, translating the token's start
/// position in the current buffer into a SourcePosition object for rendering.
diff --git a/include/clang/Parse/Action.h b/include/clang/Parse/Action.h
index fc56cc68476e..b7540f9993d0 100644
--- a/include/clang/Parse/Action.h
+++ b/include/clang/Parse/Action.h
@@ -334,6 +334,20 @@ public:
bool EnteringContext) {
return 0;
}
+
+ /// IsInvalidUnlessNestedName - This method is used for error recovery
+ /// purposes to determine whether the specified identifier is only valid as
+ /// a nested name specifier, for example a namespace name. It is
+ /// conservatively correct to always return false from this method.
+ ///
+ /// The arguments are the same as those passed to ActOnCXXNestedNameSpecifier.
+ virtual bool IsInvalidUnlessNestedName(Scope *S,
+ const CXXScopeSpec &SS,
+ IdentifierInfo &II,
+ TypeTy *ObjectType,
+ bool EnteringContext) {
+ return false;
+ }
/// ActOnCXXNestedNameSpecifier - Called during parsing of a
/// nested-name-specifier that involves a template-id, e.g.,
@@ -351,8 +365,19 @@ public:
return 0;
}
+ /// ShouldEnterDeclaratorScope - Called when a C++ scope specifier
+ /// is parsed as part of a declarator-id to determine whether a scope
+ /// should be entered.
+ ///
+ /// \param S the current scope
+ /// \param SS the scope being entered
+ /// \param isFriendDeclaration whether this is a friend declaration
+ virtual bool ShouldEnterDeclaratorScope(Scope *S, const CXXScopeSpec &SS) {
+ return false;
+ }
+
/// ActOnCXXEnterDeclaratorScope - Called when a C++ scope specifier (global
- /// scope or nested-name-specifier) is parsed, part of a declarator-id.
+ /// scope or nested-name-specifier) is parsed as part of a declarator-id.
/// After this method is called, according to [C++ 3.4.3p3], names should be
/// looked up in the declarator-id's scope, until the declarator is parsed and
/// ActOnCXXExitDeclaratorScope is called.
@@ -1250,6 +1275,10 @@ public:
///
/// \param AS the currently-active access specifier.
///
+ /// \param HasUsingKeyword true if this was declared with an
+ /// explicit 'using' keyword (i.e. if this is technically a using
+ /// declaration, not an access declaration)
+ ///
/// \param UsingLoc the location of the 'using' keyword.
///
/// \param SS the nested-name-specifier that precedes the name.
@@ -1267,6 +1296,7 @@ public:
/// \returns a representation of the using declaration.
virtual DeclPtrTy ActOnUsingDeclaration(Scope *CurScope,
AccessSpecifier AS,
+ bool HasUsingKeyword,
SourceLocation UsingLoc,
const CXXScopeSpec &SS,
UnqualifiedId &Name,
@@ -2394,6 +2424,24 @@ public:
/// \param S the scope in which the operator keyword occurs.
virtual void CodeCompleteOperatorName(Scope *S) { }
+ /// \brief Code completion after the '@' at the top level.
+ ///
+ /// \param S the scope in which the '@' occurs.
+ ///
+ /// \param ObjCImpDecl the Objective-C implementation or category
+ /// implementation.
+ ///
+ /// \param InInterface whether we are in an Objective-C interface or
+ /// protocol.
+ virtual void CodeCompleteObjCAtDirective(Scope *S, DeclPtrTy ObjCImpDecl,
+ bool InInterface) { }
+
+ /// \brief Code completion after the '@' in a statement.
+ virtual void CodeCompleteObjCAtStatement(Scope *S) { }
+
+ /// \brief Code completion after the '@' in an expression.
+ virtual void CodeCompleteObjCAtExpression(Scope *S) { }
+
/// \brief Code completion for an ObjC property decl.
///
/// This code completion action is invoked when the code-completion token is
diff --git a/include/clang/Parse/DeclSpec.h b/include/clang/Parse/DeclSpec.h
index fe899b3fdb17..b766890b7023 100644
--- a/include/clang/Parse/DeclSpec.h
+++ b/include/clang/Parse/DeclSpec.h
@@ -27,6 +27,40 @@ namespace clang {
class Declarator;
struct TemplateIdAnnotation;
+/// CXXScopeSpec - Represents a C++ nested-name-specifier or a global scope
+/// specifier.
+class CXXScopeSpec {
+ SourceRange Range;
+ void *ScopeRep;
+
+public:
+ CXXScopeSpec() : Range(), ScopeRep() { }
+
+ const SourceRange &getRange() const { return Range; }
+ void setRange(const SourceRange &R) { Range = R; }
+ void setBeginLoc(SourceLocation Loc) { Range.setBegin(Loc); }
+ void setEndLoc(SourceLocation Loc) { Range.setEnd(Loc); }
+ SourceLocation getBeginLoc() const { return Range.getBegin(); }
+ SourceLocation getEndLoc() const { return Range.getEnd(); }
+
+ ActionBase::CXXScopeTy *getScopeRep() const { return ScopeRep; }
+ void setScopeRep(ActionBase::CXXScopeTy *S) { ScopeRep = S; }
+
+ bool isEmpty() const { return !Range.isValid(); }
+ bool isNotEmpty() const { return !isEmpty(); }
+
+ /// isInvalid - An error occured during parsing of the scope specifier.
+ bool isInvalid() const { return isNotEmpty() && ScopeRep == 0; }
+
+ /// isSet - A scope specifier was resolved to a valid C++ scope.
+ bool isSet() const { return ScopeRep != 0; }
+
+ void clear() {
+ Range = SourceRange();
+ ScopeRep = 0;
+ }
+};
+
/// DeclSpec - This class captures information about "declaration specifiers",
/// which encompasses storage-class-specifiers, type-specifiers,
/// type-qualifiers, and function-specifiers.
@@ -143,6 +177,9 @@ private:
// attributes.
AttributeList *AttrList;
+ // Scope specifier for the type spec, if applicable.
+ CXXScopeSpec TypeScope;
+
// List of protocol qualifiers for objective-c classes. Used for
// protocol-qualified interfaces "NString<foo>" and protocol-qualified id
// "id<foo>".
@@ -211,6 +248,8 @@ public:
TST getTypeSpecType() const { return (TST)TypeSpecType; }
bool isTypeSpecOwned() const { return TypeSpecOwned; }
void *getTypeRep() const { return TypeRep; }
+ CXXScopeSpec &getTypeSpecScope() { return TypeScope; }
+ const CXXScopeSpec &getTypeSpecScope() const { return TypeScope; }
const SourceRange &getSourceRange() const { return Range; }
SourceLocation getTypeSpecWidthLoc() const { return TSWLoc; }
@@ -436,40 +475,6 @@ private:
IdentifierInfo *SetterName; // setter name of NULL if no setter
};
-/// CXXScopeSpec - Represents a C++ nested-name-specifier or a global scope
-/// specifier.
-class CXXScopeSpec {
- SourceRange Range;
- void *ScopeRep;
-
-public:
- CXXScopeSpec() : Range(), ScopeRep() { }
-
- const SourceRange &getRange() const { return Range; }
- void setRange(const SourceRange &R) { Range = R; }
- void setBeginLoc(SourceLocation Loc) { Range.setBegin(Loc); }
- void setEndLoc(SourceLocation Loc) { Range.setEnd(Loc); }
- SourceLocation getBeginLoc() const { return Range.getBegin(); }
- SourceLocation getEndLoc() const { return Range.getEnd(); }
-
- ActionBase::CXXScopeTy *getScopeRep() const { return ScopeRep; }
- void setScopeRep(ActionBase::CXXScopeTy *S) { ScopeRep = S; }
-
- bool isEmpty() const { return !Range.isValid(); }
- bool isNotEmpty() const { return !isEmpty(); }
-
- /// isInvalid - An error occured during parsing of the scope specifier.
- bool isInvalid() const { return isNotEmpty() && ScopeRep == 0; }
-
- /// isSet - A scope specifier was resolved to a valid C++ scope.
- bool isSet() const { return ScopeRep != 0; }
-
- void clear() {
- Range = SourceRange();
- ScopeRep = 0;
- }
-};
-
/// \brief Represents a C++ unqualified-id that has been parsed.
class UnqualifiedId {
private:
diff --git a/include/clang/Parse/Parser.h b/include/clang/Parse/Parser.h
index 81a80ebcbc61..e47de506fd1f 100644
--- a/include/clang/Parse/Parser.h
+++ b/include/clang/Parse/Parser.h
@@ -30,6 +30,7 @@ namespace clang {
class DiagnosticBuilder;
class Parser;
class PragmaUnusedHandler;
+ class ColonProtectionRAIIObject;
/// PrettyStackTraceParserEntry - If a crash happens while the parser is active,
/// an entry is printed for it.
@@ -47,6 +48,7 @@ public:
///
class Parser {
friend class PragmaUnusedHandler;
+ friend class ColonProtectionRAIIObject;
PrettyStackTraceParserEntry CrashInfo;
Preprocessor &PP;
@@ -90,26 +92,16 @@ class Parser {
/// template argument list, where the '>' closes the template
/// argument list.
bool GreaterThanIsOperator;
+
+ /// ColonIsSacred - When this is false, we aggressively try to recover from
+ /// code like "foo : bar" as if it were a typo for "foo :: bar". This is not
+ /// safe in case statements and a few other things. This is managed by the
+ /// ColonProtectionRAIIObject RAII object.
+ bool ColonIsSacred;
/// The "depth" of the template parameters currently being parsed.
unsigned TemplateParameterDepth;
- /// \brief RAII object that makes '>' behave either as an operator
- /// or as the closing angle bracket for a template argument list.
- struct GreaterThanIsOperatorScope {
- bool &GreaterThanIsOperator;
- bool OldGreaterThanIsOperator;
-
- GreaterThanIsOperatorScope(bool &GTIO, bool Val)
- : GreaterThanIsOperator(GTIO), OldGreaterThanIsOperator(GTIO) {
- GreaterThanIsOperator = Val;
- }
-
- ~GreaterThanIsOperatorScope() {
- GreaterThanIsOperator = OldGreaterThanIsOperator;
- }
- };
-
public:
Parser(Preprocessor &PP, Action &Actions);
~Parser();
@@ -759,7 +751,10 @@ private:
bool isStartOfFunctionDefinition();
DeclGroupPtrTy ParseDeclarationOrFunctionDefinition(AttributeList *Attr,
AccessSpecifier AS = AS_none);
-
+ DeclGroupPtrTy ParseDeclarationOrFunctionDefinition(ParsingDeclSpec &DS,
+ AttributeList *Attr,
+ AccessSpecifier AS = AS_none);
+
DeclPtrTy ParseFunctionDefinition(ParsingDeclarator &D,
const ParsedTemplateInfo &TemplateInfo = ParsedTemplateInfo());
void ParseKNRParamDeclarations(Declarator &D);
@@ -1087,6 +1082,7 @@ private:
private:
virtual void _anchor();
};
+ struct ObjCPropertyCallback;
void ParseStructDeclaration(DeclSpec &DS, FieldCallback &Callback);
@@ -1288,7 +1284,7 @@ private:
tok::TokenKind *After = 0);
DeclPtrTy ParseNamespace(unsigned Context, SourceLocation &DeclEnd);
- DeclPtrTy ParseLinkage(unsigned Context);
+ DeclPtrTy ParseLinkage(ParsingDeclSpec &DS, unsigned Context);
DeclPtrTy ParseUsingDirectiveOrDeclaration(unsigned Context,
SourceLocation &DeclEnd,
CXX0XAttributeList Attrs);
diff --git a/include/clang/Sema/ExternalSemaSource.h b/include/clang/Sema/ExternalSemaSource.h
index 05c56451b218..d27e29281b5a 100644
--- a/include/clang/Sema/ExternalSemaSource.h
+++ b/include/clang/Sema/ExternalSemaSource.h
@@ -34,6 +34,9 @@ public:
/// tree.
virtual void InitializeSema(Sema &S) {}
+ /// \brief Inform the semantic consumer that Sema is no longer available.
+ virtual void ForgetSema() {}
+
/// \brief Load the contents of the global method pool for a given
/// selector.
///
diff --git a/include/clang/Sema/SemaConsumer.h b/include/clang/Sema/SemaConsumer.h
index b213daf8a39e..3689a6e7a820 100644
--- a/include/clang/Sema/SemaConsumer.h
+++ b/include/clang/Sema/SemaConsumer.h
@@ -34,6 +34,9 @@ namespace clang {
/// tree.
virtual void InitializeSema(Sema &S) {}
+ /// \brief Inform the semantic consumer that Sema is no longer available.
+ virtual void ForgetSema() {}
+
// isa/cast/dyn_cast support
static bool classof(const ASTConsumer *Consumer) {
return Consumer->SemaConsumer;