summaryrefslogtreecommitdiffstats
path: root/include/clang
diff options
context:
space:
mode:
Diffstat (limited to 'include/clang')
-rw-r--r--include/clang/AST/ASTContext.h35
-rw-r--r--include/clang/AST/Attr.h42
-rw-r--r--include/clang/AST/Decl.h46
-rw-r--r--include/clang/AST/DeclBase.h4
-rw-r--r--include/clang/AST/DeclCXX.h41
-rw-r--r--include/clang/AST/DeclTemplate.h3
-rw-r--r--include/clang/AST/DeclarationName.h26
-rw-r--r--include/clang/AST/Expr.h86
-rw-r--r--include/clang/AST/ExprCXX.h626
-rw-r--r--include/clang/AST/RecordLayout.h112
-rw-r--r--include/clang/AST/Redeclarable.h13
-rw-r--r--include/clang/AST/Stmt.h95
-rw-r--r--include/clang/AST/StmtCXX.h6
-rw-r--r--include/clang/AST/StmtNodes.def9
-rw-r--r--include/clang/AST/TemplateBase.h36
-rw-r--r--include/clang/AST/Type.h30
-rw-r--r--include/clang/Analysis/Analyses/LiveVariables.h6
-rw-r--r--include/clang/Analysis/PathDiagnostic.h19
-rw-r--r--include/clang/Analysis/PathSensitive/AnalysisContext.h14
-rw-r--r--include/clang/Analysis/PathSensitive/BugReporter.h21
-rw-r--r--include/clang/Analysis/PathSensitive/BugType.h30
-rw-r--r--include/clang/Analysis/PathSensitive/Checker.h101
-rw-r--r--include/clang/Analysis/PathSensitive/CheckerVisitor.def18
-rw-r--r--include/clang/Analysis/PathSensitive/Checkers/UndefinedAssignmentChecker.h33
-rw-r--r--include/clang/Analysis/PathSensitive/ExplodedGraph.h14
-rw-r--r--include/clang/Analysis/PathSensitive/GRCoreEngine.h4
-rw-r--r--include/clang/Analysis/PathSensitive/GRExprEngine.h131
-rw-r--r--include/clang/Analysis/PathSensitive/GRState.h28
-rw-r--r--include/clang/Analysis/PathSensitive/MemRegion.h161
-rw-r--r--include/clang/Analysis/PathSensitive/ValueManager.h3
-rw-r--r--include/clang/Basic/BuiltinsX86.def4
-rw-r--r--include/clang/Basic/DiagnosticDriverKinds.td3
-rw-r--r--include/clang/Basic/DiagnosticFrontendKinds.td2
-rw-r--r--include/clang/Basic/DiagnosticGroups.td7
-rw-r--r--include/clang/Basic/DiagnosticLexKinds.td2
-rw-r--r--include/clang/Basic/DiagnosticParseKinds.td11
-rw-r--r--include/clang/Basic/DiagnosticSemaKinds.td58
-rw-r--r--include/clang/Basic/IdentifierTable.h9
-rw-r--r--include/clang/Basic/LangOptions.h15
-rw-r--r--include/clang/Basic/OnDiskHashTable.h1
-rw-r--r--include/clang/Basic/TargetInfo.h3
-rw-r--r--include/clang/Basic/TokenKinds.def111
-rw-r--r--include/clang/CodeGen/CodeGenOptions.h52
-rw-r--r--include/clang/Driver/ArgList.h83
-rw-r--r--include/clang/Driver/CC1Options.h2
-rw-r--r--include/clang/Driver/CC1Options.td395
-rw-r--r--include/clang/Driver/Makefile4
-rw-r--r--include/clang/Driver/OptParser.td15
-rw-r--r--include/clang/Driver/OptSpecifier.h3
-rw-r--r--include/clang/Driver/Options.h2
-rw-r--r--include/clang/Frontend/ASTConsumers.h1
-rw-r--r--include/clang/Frontend/ASTUnit.h43
-rw-r--r--include/clang/Frontend/AnalysisConsumer.h2
-rw-r--r--include/clang/Frontend/CommandLineSourceLoc.h49
-rw-r--r--include/clang/Frontend/CompilerInstance.h18
-rw-r--r--include/clang/Frontend/CompilerInvocation.h18
-rw-r--r--include/clang/Frontend/DeclXML.def58
-rw-r--r--include/clang/Frontend/FrontendAction.h17
-rw-r--r--include/clang/Frontend/FrontendOptions.h2
-rw-r--r--include/clang/Frontend/LangStandard.h83
-rw-r--r--include/clang/Frontend/LangStandards.def83
-rw-r--r--include/clang/Frontend/PCHBitCodes.h8
-rw-r--r--include/clang/Frontend/PathDiagnosticClients.h2
-rw-r--r--include/clang/Frontend/StmtXML.def89
-rw-r--r--include/clang/Frontend/TextDiagnosticBuffer.h4
-rw-r--r--include/clang/Lex/Lexer.h5
-rw-r--r--include/clang/Lex/Preprocessor.h6
-rw-r--r--include/clang/Parse/Action.h152
-rw-r--r--include/clang/Parse/AttributeList.h35
-rw-r--r--include/clang/Parse/DeclSpec.h21
-rw-r--r--include/clang/Parse/Parser.h74
-rw-r--r--include/clang/Sema/CodeCompleteConsumer.h22
72 files changed, 2425 insertions, 942 deletions
diff --git a/include/clang/AST/ASTContext.h b/include/clang/AST/ASTContext.h
index f9d2f71..4f29e5d 100644
--- a/include/clang/AST/ASTContext.h
+++ b/include/clang/AST/ASTContext.h
@@ -120,8 +120,7 @@ class ASTContext {
QualType ObjCIdTypedefType;
/// ObjCSelType - another pseudo built-in typedef type (set by Sema).
- QualType ObjCSelType;
- const RecordType *SelStructType;
+ QualType ObjCSelTypedefType;
/// ObjCProtoType - another pseudo built-in typedef type (set by Sema).
QualType ObjCProtoType;
@@ -244,6 +243,7 @@ public:
// pseudo-builtins
QualType ObjCIdRedefinitionType;
QualType ObjCClassRedefinitionType;
+ QualType ObjCSelRedefinitionType;
/// \brief Source ranges for all of the comments in the source file,
/// sorted in order of appearance in the translation unit.
@@ -316,7 +316,7 @@ public:
CanQualType OverloadTy;
CanQualType DependentTy;
CanQualType UndeducedAutoTy;
- CanQualType ObjCBuiltinIdTy, ObjCBuiltinClassTy;
+ CanQualType ObjCBuiltinIdTy, ObjCBuiltinClassTy, ObjCBuiltinSelTy;
ASTContext(const LangOptions& LOpts, SourceManager &SM, const TargetInfo &t,
IdentifierTable &idents, SelectorTable &sels,
@@ -532,8 +532,7 @@ public:
QualType Canon = QualType());
QualType getTemplateSpecializationType(TemplateName T,
- const TemplateArgumentLoc *Args,
- unsigned NumArgs,
+ const TemplateArgumentListInfo &Args,
QualType Canon = QualType());
QualType getQualifiedNameType(NestedNameSpecifier *NNS,
@@ -696,7 +695,7 @@ public:
void setObjCIdType(QualType T);
void setObjCSelType(QualType T);
- QualType getObjCSelType() const { return ObjCSelType; }
+ QualType getObjCSelType() const { return ObjCSelTypedefType; }
void setObjCProtoType(QualType QT);
QualType getObjCProtoType() const { return ObjCProtoType; }
@@ -734,6 +733,8 @@ public:
return getExtQualType(T, Qs);
}
+ DeclarationName getNameForTemplate(TemplateName Name);
+
TemplateName getQualifiedTemplateName(NestedNameSpecifier *NNS,
bool TemplateKeyword,
TemplateDecl *Template);
@@ -796,6 +797,20 @@ public:
return getTypeInfo(T).first;
}
+ /// getByteWidth - Return the size of a byte, in bits
+ uint64_t getByteSize() {
+ return getTypeSize(CharTy);
+ }
+
+ /// getTypeSizeInBytes - Return the size of the specified type, in bytes.
+ /// This method does not work on incomplete types.
+ uint64_t getTypeSizeInBytes(QualType T) {
+ return getTypeSize(T) / getByteSize();
+ }
+ uint64_t getTypeSizeInBytes(const Type *T) {
+ return getTypeSize(T) / getByteSize();
+ }
+
/// getTypeAlign - Return the ABI-specified alignment of a type, in bits.
/// This method does not work on incomplete types.
unsigned getTypeAlign(QualType T) {
@@ -811,10 +826,7 @@ public:
/// a data type.
unsigned getPreferredTypeAlign(const Type *T);
- /// getDeclAlignInBytes - Return the alignment of the specified decl
- /// that should be returned by __alignof(). Note that bitfields do
- /// not have a valid alignment, so this method will assert on them.
- unsigned getDeclAlignInBytes(const Decl *D);
+ unsigned getDeclAlignInBytes(const Decl *D, bool RefAsPointee = false);
/// getASTRecordLayout - Get or compute information about the layout of the
/// specified record (struct/union/class), which indicates its size and field
@@ -1023,8 +1035,7 @@ public:
return T == ObjCClassTypedefType;
}
bool isObjCSelType(QualType T) const {
- assert(SelStructType && "isObjCSelType used before 'SEL' type is built");
- return T->getAsStructureType() == SelStructType;
+ return T == ObjCSelTypedefType;
}
bool QualifiedIdConformsQualifiedId(QualType LHS, QualType RHS);
bool ObjCQualifiedIdTypesAreCompatible(QualType LHS, QualType RHS,
diff --git a/include/clang/AST/Attr.h b/include/clang/AST/Attr.h
index b36ff12..2c7ab9d 100644
--- a/include/clang/AST/Attr.h
+++ b/include/clang/AST/Attr.h
@@ -15,12 +15,12 @@
#define LLVM_CLANG_AST_ATTR_H
#include "llvm/Support/Casting.h"
-using llvm::dyn_cast;
-
+#include "llvm/ADT/StringRef.h"
#include <cassert>
#include <cstring>
#include <string>
#include <algorithm>
+using llvm::dyn_cast;
namespace clang {
class ASTContext;
@@ -49,6 +49,7 @@ public:
AnalyzerNoReturn, // Clang-specific.
Annotate,
AsmLabel, // Represent GCC asm label extension.
+ BaseCheck,
Blocks,
CDecl,
Cleanup,
@@ -59,9 +60,11 @@ public:
Deprecated,
Destructor,
FastCall,
+ Final,
Format,
FormatArg,
GNUInline,
+ Hiding,
IBOutletKind, // Clang-specific. Use "Kind" suffix to not conflict with
Malloc,
NoDebug,
@@ -71,6 +74,7 @@ public:
NoThrow,
ObjCException,
ObjCNSObject,
+ Override,
CFReturnsRetained, // Clang/Checker-specific.
NSReturnsRetained, // Clang/Checker-specific.
Overloadable, // Clang-specific
@@ -184,12 +188,24 @@ public:
class AlignedAttr : public Attr {
unsigned Alignment;
public:
- AlignedAttr(unsigned alignment) : Attr(Aligned), Alignment(alignment) {}
+ AlignedAttr(unsigned alignment)
+ : Attr(Aligned), Alignment(alignment) {}
/// getAlignment - The specified alignment in bits.
unsigned getAlignment() const { return Alignment; }
+
+ /// getMaxAlignment - Get the maximum alignment of attributes on this list.
+ unsigned getMaxAlignment() const {
+ const AlignedAttr *Next = getNext<AlignedAttr>();
+ if (Next)
+ return std::max(Next->getMaxAlignment(), Alignment);
+ else
+ return Alignment;
+ }
- virtual Attr* clone(ASTContext &C) const { return ::new (C) AlignedAttr(Alignment); }
+ virtual Attr* clone(ASTContext &C) const {
+ return ::new (C) AlignedAttr(Alignment);
+ }
// Implement isa/cast/dyncast/etc.
static bool classof(const Attr *A) {
@@ -201,7 +217,7 @@ public:
class AnnotateAttr : public Attr {
std::string Annotation;
public:
- AnnotateAttr(const std::string &ann) : Attr(Annotate), Annotation(ann) {}
+ AnnotateAttr(llvm::StringRef ann) : Attr(Annotate), Annotation(ann) {}
const std::string& getAnnotation() const { return Annotation; }
@@ -217,7 +233,7 @@ public:
class AsmLabelAttr : public Attr {
std::string Label;
public:
- AsmLabelAttr(const std::string &L) : Attr(AsmLabel), Label(L) {}
+ AsmLabelAttr(llvm::StringRef L) : Attr(AsmLabel), Label(L) {}
const std::string& getLabel() const { return Label; }
@@ -235,7 +251,7 @@ DEF_SIMPLE_ATTR(AlwaysInline);
class AliasAttr : public Attr {
std::string Aliasee;
public:
- AliasAttr(const std::string &aliasee) : Attr(Alias), Aliasee(aliasee) {}
+ AliasAttr(llvm::StringRef aliasee) : Attr(Alias), Aliasee(aliasee) {}
const std::string& getAliasee() const { return Aliasee; }
@@ -304,11 +320,12 @@ DEF_SIMPLE_ATTR(Malloc);
DEF_SIMPLE_ATTR(NoReturn);
DEF_SIMPLE_ATTR(AnalyzerNoReturn);
DEF_SIMPLE_ATTR(Deprecated);
+DEF_SIMPLE_ATTR(Final);
class SectionAttr : public Attr {
std::string Name;
public:
- SectionAttr(const std::string &N) : Attr(Section), Name(N) {}
+ SectionAttr(llvm::StringRef N) : Attr(Section), Name(N) {}
const std::string& getName() const { return Name; }
@@ -367,11 +384,11 @@ class FormatAttr : public Attr {
std::string Type;
int formatIdx, firstArg;
public:
- FormatAttr(const std::string &type, int idx, int first) : Attr(Format),
+ FormatAttr(llvm::StringRef type, int idx, int first) : Attr(Format),
Type(type), formatIdx(idx), firstArg(first) {}
const std::string& getType() const { return Type; }
- void setType(const std::string &type) { Type = type; }
+ void setType(llvm::StringRef type) { Type = type; }
int getFormatIdx() const { return formatIdx; }
int getFirstArg() const { return firstArg; }
@@ -544,6 +561,11 @@ public:
DEF_SIMPLE_ATTR(CFReturnsRetained);
DEF_SIMPLE_ATTR(NSReturnsRetained);
+// C++0x member checking attributes.
+DEF_SIMPLE_ATTR(BaseCheck);
+DEF_SIMPLE_ATTR(Hiding);
+DEF_SIMPLE_ATTR(Override);
+
#undef DEF_SIMPLE_ATTR
} // end namespace clang
diff --git a/include/clang/AST/Decl.h b/include/clang/AST/Decl.h
index ac79a91..f794477 100644
--- a/include/clang/AST/Decl.h
+++ b/include/clang/AST/Decl.h
@@ -54,6 +54,32 @@ public:
TypeLoc getTypeLoc() const;
};
+/// UnresolvedSet - A set of unresolved declarations. This is needed
+/// in a lot of places, but isn't really worth breaking into its own
+/// header right now.
+class UnresolvedSet {
+ typedef llvm::SmallVector<NamedDecl*, 4> DeclsTy;
+ DeclsTy Decls;
+
+public:
+ void addDecl(NamedDecl *D) {
+ Decls.push_back(D);
+ }
+
+ bool replace(const NamedDecl* Old, NamedDecl *New) {
+ for (DeclsTy::iterator I = Decls.begin(), E = Decls.end(); I != E; ++I)
+ if (*I == Old)
+ return (*I = New, true);
+ return false;
+ }
+
+ unsigned size() const { return Decls.size(); }
+
+ typedef DeclsTy::const_iterator iterator;
+ iterator begin() const { return Decls.begin(); }
+ iterator end() const { return Decls.end(); }
+};
+
/// TranslationUnitDecl - The top declaration context.
class TranslationUnitDecl : public Decl, public DeclContext {
ASTContext &Ctx;
@@ -172,6 +198,26 @@ public:
/// \brief Determine whether this declaration has linkage.
bool hasLinkage() const;
+ /// \brief Describes the different kinds of linkage
+ /// (C++ [basic.link], C99 6.2.2) that an entity may have.
+ enum Linkage {
+ /// \brief No linkage, which means that the entity is unique and
+ /// can only be referred to from within its scope.
+ NoLinkage = 0,
+
+ /// \brief Internal linkage, which indicates that the entity can
+ /// be referred to from within the translation unit (but not other
+ /// translation units).
+ InternalLinkage,
+
+ /// \brief External linkage, which indicates that the entity can
+ /// be referred to from other translation units.
+ ExternalLinkage
+ };
+
+ /// \brief Determine what kind of linkage this entity has.
+ Linkage getLinkage() const;
+
/// \brief Looks through UsingDecls and ObjCCompatibleAliasDecls for
/// the underlying named decl.
NamedDecl *getUnderlyingDecl();
diff --git a/include/clang/AST/DeclBase.h b/include/clang/AST/DeclBase.h
index 79f7663..e1f948f 100644
--- a/include/clang/AST/DeclBase.h
+++ b/include/clang/AST/DeclBase.h
@@ -503,12 +503,12 @@ private:
/// PrettyStackTraceDecl - If a crash occurs, indicate that it happened when
/// doing something to a specific decl.
class PrettyStackTraceDecl : public llvm::PrettyStackTraceEntry {
- Decl *TheDecl;
+ const Decl *TheDecl;
SourceLocation Loc;
SourceManager &SM;
const char *Message;
public:
- PrettyStackTraceDecl(Decl *theDecl, SourceLocation L,
+ PrettyStackTraceDecl(const Decl *theDecl, SourceLocation L,
SourceManager &sm, const char *Msg)
: TheDecl(theDecl), Loc(L), SM(sm), Message(Msg) {}
diff --git a/include/clang/AST/DeclCXX.h b/include/clang/AST/DeclCXX.h
index e5bf78c..990403e7 100644
--- a/include/clang/AST/DeclCXX.h
+++ b/include/clang/AST/DeclCXX.h
@@ -376,13 +376,13 @@ class CXXRecordDecl : public RecordDecl {
/// of this C++ class (but not its inherited conversion
/// functions). Each of the entries in this overload set is a
/// CXXConversionDecl.
- OverloadedFunctionDecl Conversions;
+ UnresolvedSet Conversions;
/// VisibleConversions - Overload set containing the conversion functions
/// of this C++ class and all those inherited conversion functions that
/// are visible in this class. Each of the entries in this overload set is
/// a CXXConversionDecl or a FunctionTemplateDecl.
- OverloadedFunctionDecl VisibleConversions;
+ UnresolvedSet VisibleConversions;
/// \brief The template or declaration that this declaration
/// describes or was instantiated from, respectively.
@@ -400,7 +400,7 @@ class CXXRecordDecl : public RecordDecl {
const llvm::SmallPtrSet<CanQualType, 8> &TopConversionsTypeSet,
const llvm::SmallPtrSet<CanQualType, 8> &HiddenConversionTypes);
void collectConversionFunctions(
- llvm::SmallPtrSet<CanQualType, 8>& ConversionsTypeSet);
+ llvm::SmallPtrSet<CanQualType, 8>& ConversionsTypeSet) const;
protected:
CXXRecordDecl(Kind K, TagKind TK, DeclContext *DC,
@@ -581,22 +581,34 @@ public:
/// getConversions - Retrieve the overload set containing all of the
/// conversion functions in this class.
- OverloadedFunctionDecl *getConversionFunctions() {
+ UnresolvedSet *getConversionFunctions() {
assert((this->isDefinition() ||
cast<RecordType>(getTypeForDecl())->isBeingDefined()) &&
"getConversionFunctions() called on incomplete type");
return &Conversions;
}
- const OverloadedFunctionDecl *getConversionFunctions() const {
+ const UnresolvedSet *getConversionFunctions() const {
assert((this->isDefinition() ||
cast<RecordType>(getTypeForDecl())->isBeingDefined()) &&
"getConversionFunctions() called on incomplete type");
return &Conversions;
}
+ typedef UnresolvedSet::iterator conversion_iterator;
+ conversion_iterator conversion_begin() const { return Conversions.begin(); }
+ conversion_iterator conversion_end() const { return Conversions.end(); }
+
+ /// Replaces a conversion function with a new declaration.
+ ///
+ /// Returns true if the old conversion was found.
+ bool replaceConversion(const NamedDecl* Old, NamedDecl *New) {
+ return Conversions.replace(Old, New);
+ }
+
/// getVisibleConversionFunctions - get all conversion functions visible
/// in current class; including conversion function templates.
- OverloadedFunctionDecl *getVisibleConversionFunctions();
+ const UnresolvedSet *getVisibleConversionFunctions();
+
/// addVisibleConversionFunction - Add a new conversion function to the
/// list of visible conversion functions.
void addVisibleConversionFunction(CXXConversionDecl *ConvDecl);
@@ -1502,9 +1514,9 @@ class UsingDirectiveDecl : public NamedDecl {
SourceLocation IdentLoc;
/// NominatedNamespace - Namespace nominated by using-directive.
- NamespaceDecl *NominatedNamespace;
+ NamedDecl *NominatedNamespace;
- /// Enclosing context containing both using-directive and nomintated
+ /// Enclosing context containing both using-directive and nominated
/// namespace.
DeclContext *CommonAncestor;
@@ -1520,12 +1532,12 @@ class UsingDirectiveDecl : public NamedDecl {
SourceRange QualifierRange,
NestedNameSpecifier *Qualifier,
SourceLocation IdentLoc,
- NamespaceDecl *Nominated,
+ NamedDecl *Nominated,
DeclContext *CommonAncestor)
: NamedDecl(Decl::UsingDirective, DC, L, getName()),
NamespaceLoc(NamespcLoc), QualifierRange(QualifierRange),
Qualifier(Qualifier), IdentLoc(IdentLoc),
- NominatedNamespace(Nominated? Nominated->getOriginalNamespace() : 0),
+ NominatedNamespace(Nominated),
CommonAncestor(CommonAncestor) {
}
@@ -1538,8 +1550,13 @@ public:
/// name of the namespace.
NestedNameSpecifier *getQualifier() const { return Qualifier; }
+ NamedDecl *getNominatedNamespaceAsWritten() { return NominatedNamespace; }
+ const NamedDecl *getNominatedNamespaceAsWritten() const {
+ return NominatedNamespace;
+ }
+
/// getNominatedNamespace - Returns namespace nominated by using-directive.
- NamespaceDecl *getNominatedNamespace() { return NominatedNamespace; }
+ NamespaceDecl *getNominatedNamespace();
const NamespaceDecl *getNominatedNamespace() const {
return const_cast<UsingDirectiveDecl*>(this)->getNominatedNamespace();
@@ -1562,7 +1579,7 @@ public:
SourceRange QualifierRange,
NestedNameSpecifier *Qualifier,
SourceLocation IdentLoc,
- NamespaceDecl *Nominated,
+ NamedDecl *Nominated,
DeclContext *CommonAncestor);
static bool classof(const Decl *D) {
diff --git a/include/clang/AST/DeclTemplate.h b/include/clang/AST/DeclTemplate.h
index 14f6660..3ecc4bb 100644
--- a/include/clang/AST/DeclTemplate.h
+++ b/include/clang/AST/DeclTemplate.h
@@ -955,8 +955,7 @@ public:
TemplateParameterList *Params,
ClassTemplateDecl *SpecializedTemplate,
TemplateArgumentListBuilder &Builder,
- TemplateArgumentLoc *ArgInfos,
- unsigned NumArgInfos,
+ const TemplateArgumentListInfo &ArgInfos,
ClassTemplatePartialSpecializationDecl *PrevDecl);
/// Get the list of template parameters
diff --git a/include/clang/AST/DeclarationName.h b/include/clang/AST/DeclarationName.h
index a30f6e8..676bd2c 100644
--- a/include/clang/AST/DeclarationName.h
+++ b/include/clang/AST/DeclarationName.h
@@ -25,6 +25,7 @@ namespace llvm {
namespace clang {
class CXXSpecialName;
class CXXOperatorIdName;
+ class CXXLiteralOperatorIdName;
class DeclarationNameExtra;
class IdentifierInfo;
class MultiKeywordSelector;
@@ -48,6 +49,7 @@ public:
CXXDestructorName,
CXXConversionFunctionName,
CXXOperatorName,
+ CXXLiteralOperatorName,
CXXUsingDirective
};
@@ -115,6 +117,12 @@ private:
return 0;
}
+ CXXLiteralOperatorIdName *getAsCXXLiteralOperatorIdName() const {
+ if (getNameKind() == CXXLiteralOperatorName)
+ return reinterpret_cast<CXXLiteralOperatorIdName *>(Ptr & ~PtrMask);
+ return 0;
+ }
+
// Construct a declaration name from the name of a C++ constructor,
// destructor, or conversion function.
DeclarationName(CXXSpecialName *Name)
@@ -131,6 +139,12 @@ private:
Ptr |= StoredDeclarationNameExtra;
}
+ DeclarationName(CXXLiteralOperatorIdName *Name)
+ : Ptr(reinterpret_cast<uintptr_t>(Name)) {
+ assert((Ptr & PtrMask) == 0 && "Improperly aligned CXXLiteralOperatorId");
+ Ptr |= StoredDeclarationNameExtra;
+ }
+
/// Construct a declaration name from a raw pointer.
DeclarationName(uintptr_t Ptr) : Ptr(Ptr) { }
@@ -201,7 +215,7 @@ public:
N.Ptr = reinterpret_cast<uintptr_t> (P);
return N;
}
-
+
static DeclarationName getFromOpaqueInteger(uintptr_t P) {
DeclarationName N;
N.Ptr = P;
@@ -218,6 +232,10 @@ public:
/// kind of overloaded operator.
OverloadedOperatorKind getCXXOverloadedOperator() const;
+ /// getCXXLiteralIdentifier - If this name is the name of a literal
+ /// operator, retrieve the identifier associated with it.
+ IdentifierInfo *getCXXLiteralIdentifier() const;
+
/// getObjCSelector - Get the Objective-C selector stored in this
/// declaration name.
Selector getObjCSelector() const;
@@ -293,7 +311,7 @@ public:
/// getIdentifier - Create a declaration name that is a simple
/// identifier.
- DeclarationName getIdentifier(IdentifierInfo *ID) {
+ DeclarationName getIdentifier(const IdentifierInfo *ID) {
return DeclarationName(ID);
}
@@ -324,6 +342,10 @@ public:
/// getCXXOperatorName - Get the name of the overloadable C++
/// operator corresponding to Op.
DeclarationName getCXXOperatorName(OverloadedOperatorKind Op);
+
+ /// getCXXLiteralOperatorName - Get the name of the literal operator function
+ /// with II as the identifier.
+ DeclarationName getCXXLiteralOperatorName(IdentifierInfo *II);
};
/// Insertion operator for diagnostics. This allows sending DeclarationName's
diff --git a/include/clang/AST/Expr.h b/include/clang/AST/Expr.h
index dfc5b13..7cf9aab 100644
--- a/include/clang/AST/Expr.h
+++ b/include/clang/AST/Expr.h
@@ -35,6 +35,7 @@ namespace clang {
class CXXOperatorCallExpr;
class CXXMemberCallExpr;
class TemplateArgumentLoc;
+ class TemplateArgumentListInfo;
/// Expr - This represents one expression. Note that Expr's are subclasses of
/// Stmt. This allows an expression to be transparently used any place a Stmt
@@ -366,6 +367,10 @@ struct ExplicitTemplateArgumentList {
const TemplateArgumentLoc *getTemplateArgs() const {
return reinterpret_cast<const TemplateArgumentLoc *> (this + 1);
}
+
+ void initializeFrom(const TemplateArgumentListInfo &List);
+ void copyInto(TemplateArgumentListInfo &List) const;
+ static std::size_t sizeFor(const TemplateArgumentListInfo &List);
};
/// DeclRefExpr - [C99 6.5.1p2] - A reference to a declared variable, function,
@@ -423,31 +428,24 @@ class DeclRefExpr : public Expr {
DeclRefExpr(NestedNameSpecifier *Qualifier, SourceRange QualifierRange,
NamedDecl *D, SourceLocation NameLoc,
- bool HasExplicitTemplateArgumentList,
- SourceLocation LAngleLoc,
- const TemplateArgumentLoc *ExplicitTemplateArgs,
- unsigned NumExplicitTemplateArgs,
- SourceLocation RAngleLoc,
- QualType T, bool TD, bool VD);
+ const TemplateArgumentListInfo *TemplateArgs,
+ QualType T);
protected:
- // FIXME: Eventually, this constructor will go away and all subclasses
- // will have to provide the type- and value-dependent flags.
- DeclRefExpr(StmtClass SC, NamedDecl *d, QualType t, SourceLocation l) :
- Expr(SC, t), DecoratedD(d, 0), Loc(l) {}
+ /// \brief Computes the type- and value-dependence flags for this
+ /// declaration reference expression.
+ void computeDependence();
- DeclRefExpr(StmtClass SC, NamedDecl *d, QualType t, SourceLocation l, bool TD,
- bool VD) :
- Expr(SC, t, TD, VD), DecoratedD(d, 0), Loc(l) {}
+ DeclRefExpr(StmtClass SC, NamedDecl *d, QualType t, SourceLocation l) :
+ Expr(SC, t, false, false), DecoratedD(d, 0), Loc(l) {
+ computeDependence();
+ }
public:
- // FIXME: Eventually, this constructor will go away and all clients
- // will have to provide the type- and value-dependent flags.
DeclRefExpr(NamedDecl *d, QualType t, SourceLocation l) :
- Expr(DeclRefExprClass, t), DecoratedD(d, 0), Loc(l) {}
-
- DeclRefExpr(NamedDecl *d, QualType t, SourceLocation l, bool TD, bool VD) :
- Expr(DeclRefExprClass, t, TD, VD), DecoratedD(d, 0), Loc(l) {}
+ Expr(DeclRefExprClass, t, false, false), DecoratedD(d, 0), Loc(l) {
+ computeDependence();
+ }
/// \brief Construct an empty declaration reference expression.
explicit DeclRefExpr(EmptyShell Empty)
@@ -458,19 +456,8 @@ public:
SourceRange QualifierRange,
NamedDecl *D,
SourceLocation NameLoc,
- QualType T, bool TD, bool VD);
-
- static DeclRefExpr *Create(ASTContext &Context,
- NestedNameSpecifier *Qualifier,
- SourceRange QualifierRange,
- NamedDecl *D,
- SourceLocation NameLoc,
- bool HasExplicitTemplateArgumentList,
- SourceLocation LAngleLoc,
- const TemplateArgumentLoc *ExplicitTemplateArgs,
- unsigned NumExplicitTemplateArgs,
- SourceLocation RAngleLoc,
- QualType T, bool TD, bool VD);
+ QualType T,
+ const TemplateArgumentListInfo *TemplateArgs = 0);
NamedDecl *getDecl() { return DecoratedD.getPointer(); }
const NamedDecl *getDecl() const { return DecoratedD.getPointer(); }
@@ -508,6 +495,13 @@ public:
bool hasExplicitTemplateArgumentList() const {
return DecoratedD.getInt() & HasExplicitTemplateArgumentListFlag;
}
+
+ /// \brief Copies the template arguments (if present) into the given
+ /// structure.
+ void copyTemplateArgumentsInto(TemplateArgumentListInfo &List) const {
+ if (hasExplicitTemplateArgumentList())
+ getExplicitTemplateArgumentList()->copyInto(List);
+ }
/// \brief Retrieve the location of the left angle bracket following the
/// member name ('<'), if any.
@@ -546,8 +540,7 @@ public:
}
static bool classof(const Stmt *T) {
- return T->getStmtClass() == DeclRefExprClass ||
- T->getStmtClass() == CXXConditionDeclExprClass;
+ return T->getStmtClass() == DeclRefExprClass;
}
static bool classof(const DeclRefExpr *) { return true; }
@@ -1313,9 +1306,7 @@ class MemberExpr : public Expr {
MemberExpr(Expr *base, bool isarrow, NestedNameSpecifier *qual,
SourceRange qualrange, NamedDecl *memberdecl, SourceLocation l,
- bool has_explicit, SourceLocation langle,
- const TemplateArgumentLoc *targs, unsigned numtargs,
- SourceLocation rangle, QualType ty);
+ const TemplateArgumentListInfo *targs, QualType ty);
public:
MemberExpr(Expr *base, bool isarrow, NamedDecl *memberdecl, SourceLocation l,
@@ -1334,11 +1325,7 @@ public:
NestedNameSpecifier *qual, SourceRange qualrange,
NamedDecl *memberdecl,
SourceLocation l,
- bool has_explicit,
- SourceLocation langle,
- const TemplateArgumentLoc *targs,
- unsigned numtargs,
- SourceLocation rangle,
+ const TemplateArgumentListInfo *targs,
QualType ty);
void setBase(Expr *E) { Base = E; }
@@ -1378,10 +1365,17 @@ public:
/// \brief Determines whether this member expression actually had a C++
/// template argument list explicitly specified, e.g., x.f<int>.
- bool hasExplicitTemplateArgumentList() {
+ bool hasExplicitTemplateArgumentList() const {
return HasExplicitTemplateArgumentList;
}
+ /// \brief Copies the template arguments (if present) into the given
+ /// structure.
+ void copyTemplateArgumentsInto(TemplateArgumentListInfo &List) const {
+ if (hasExplicitTemplateArgumentList())
+ getExplicitTemplateArgumentList()->copyInto(List);
+ }
+
/// \brief Retrieve the location of the left angle bracket following the
/// member name ('<'), if any.
SourceLocation getLAngleLoc() const {
@@ -1579,7 +1573,11 @@ public:
CK_FloatingToIntegral,
/// CK_FloatingCast - Casting between floating types of different size.
- CK_FloatingCast
+ CK_FloatingCast,
+
+ /// CK_MemberPointerToBoolean - Member pointer to boolean
+ CK_MemberPointerToBoolean
+
};
private:
diff --git a/include/clang/AST/ExprCXX.h b/include/clang/AST/ExprCXX.h
index 9e6fd4f..23844ce 100644
--- a/include/clang/AST/ExprCXX.h
+++ b/include/clang/AST/ExprCXX.h
@@ -17,6 +17,7 @@
#include "clang/Basic/TypeTraits.h"
#include "clang/AST/Expr.h"
#include "clang/AST/Decl.h"
+#include "clang/AST/TemplateBase.h"
namespace clang {
@@ -24,6 +25,7 @@ namespace clang {
class CXXDestructorDecl;
class CXXMethodDecl;
class CXXTemporary;
+ class TemplateArgumentListInfo;
//===--------------------------------------------------------------------===//
// C++ Expressions.
@@ -669,40 +671,6 @@ public:
virtual child_iterator child_end();
};
-/// CXXConditionDeclExpr - Condition declaration of a if/switch/while/for
-/// statement, e.g: "if (int x = f()) {...}".
-/// The main difference with DeclRefExpr is that CXXConditionDeclExpr owns the
-/// decl that it references.
-///
-class CXXConditionDeclExpr : public DeclRefExpr {
-public:
- CXXConditionDeclExpr(SourceLocation startLoc,
- SourceLocation eqLoc, VarDecl *var)
- : DeclRefExpr(CXXConditionDeclExprClass, var,
- var->getType().getNonReferenceType(), startLoc,
- var->getType()->isDependentType(),
- /*FIXME:integral constant?*/
- var->getType()->isDependentType()) {}
-
- SourceLocation getStartLoc() const { return getLocation(); }
-
- VarDecl *getVarDecl() { return cast<VarDecl>(getDecl()); }
- const VarDecl *getVarDecl() const { return cast<VarDecl>(getDecl()); }
-
- virtual SourceRange getSourceRange() const {
- return SourceRange(getStartLoc(), getVarDecl()->getInit()->getLocEnd());
- }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == CXXConditionDeclExprClass;
- }
- static bool classof(const CXXConditionDeclExpr *) { return true; }
-
- // Iterators
- virtual child_iterator child_begin();
- virtual child_iterator child_end();
-};
-
/// CXXNewExpr - A new expression for memory allocation and constructor calls,
/// e.g: "new CXXNewExpr(foo)".
class CXXNewExpr : public Expr {
@@ -975,52 +943,6 @@ public:
virtual child_iterator child_end();
};
-/// \brief Represents the name of a function that has not been
-/// resolved to any declaration.
-///
-/// Unresolved function names occur when a function name is
-/// encountered prior to an open parentheses ('(') in a C++ function
-/// call, and the function name itself did not resolve to a
-/// declaration. These function names can only be resolved when they
-/// form the postfix-expression of a function call, so that
-/// argument-dependent lookup finds declarations corresponding to
-/// these functions.
-
-/// @code
-/// template<typename T> void f(T x) {
-/// g(x); // g is an unresolved function name (that is also a dependent name)
-/// }
-/// @endcode
-class UnresolvedFunctionNameExpr : public Expr {
- /// The name that was present in the source
- DeclarationName Name;
-
- /// The location of this name in the source code
- SourceLocation Loc;
-
-public:
- UnresolvedFunctionNameExpr(DeclarationName N, QualType T, SourceLocation L)
- : Expr(UnresolvedFunctionNameExprClass, T, false, false), Name(N), Loc(L) { }
-
- /// \brief Retrieves the name that occurred in the source code.
- DeclarationName getName() const { return Name; }
-
- /// getLocation - Retrieves the location in the source code where
- /// the name occurred.
- SourceLocation getLocation() const { return Loc; }
-
- virtual SourceRange getSourceRange() const { return SourceRange(Loc); }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == UnresolvedFunctionNameExprClass;
- }
- static bool classof(const UnresolvedFunctionNameExpr *) { return true; }
-
- // Iterators
- virtual child_iterator child_begin();
- virtual child_iterator child_end();
-};
-
/// UnaryTypeTraitExpr - A GCC or MS unary type trait, as used in the
/// implementation of TR1/C++0x type trait templates.
/// Example:
@@ -1063,21 +985,177 @@ public:
virtual child_iterator child_end();
};
+/// \brief A reference to a name which we were able to look up during
+/// parsing but could not resolve to a specific declaration. This
+/// arises in several ways:
+/// * we might be waiting for argument-dependent lookup
+/// * the name might resolve to an overloaded function
+/// and eventually:
+/// * the lookup might have included a function template
+/// These never include UnresolvedUsingValueDecls, which are always
+/// class members and therefore appear only in
+/// UnresolvedMemberLookupExprs.
+class UnresolvedLookupExpr : public Expr {
+ /// The results. These are undesugared, which is to say, they may
+ /// include UsingShadowDecls.
+ UnresolvedSet Results;
+
+ /// The name declared.
+ DeclarationName Name;
+
+ /// The qualifier given, if any.
+ NestedNameSpecifier *Qualifier;
+
+ /// The source range of the nested name specifier.
+ SourceRange QualifierRange;
+
+ /// The location of the name.
+ SourceLocation NameLoc;
+
+ /// True if these lookup results should be extended by
+ /// argument-dependent lookup if this is the operand of a function
+ /// call.
+ bool RequiresADL;
+
+ /// True if these lookup results are overloaded. This is pretty
+ /// trivially rederivable if we urgently need to kill this field.
+ bool Overloaded;
+
+ /// True if the name looked up had explicit template arguments.
+ /// This requires all the results to be function templates.
+ bool HasExplicitTemplateArgs;
+
+ UnresolvedLookupExpr(QualType T, bool Dependent,
+ NestedNameSpecifier *Qualifier, SourceRange QRange,
+ DeclarationName Name, SourceLocation NameLoc,
+ bool RequiresADL, bool Overloaded, bool HasTemplateArgs)
+ : Expr(UnresolvedLookupExprClass, T, Dependent, Dependent),
+ Name(Name), Qualifier(Qualifier), QualifierRange(QRange),
+ NameLoc(NameLoc), RequiresADL(RequiresADL), Overloaded(Overloaded),
+ HasExplicitTemplateArgs(HasTemplateArgs)
+ {}
+
+public:
+ static UnresolvedLookupExpr *Create(ASTContext &C,
+ bool Dependent,
+ NestedNameSpecifier *Qualifier,
+ SourceRange QualifierRange,
+ DeclarationName Name,
+ SourceLocation NameLoc,
+ bool ADL, bool Overloaded) {
+ return new(C) UnresolvedLookupExpr(Dependent ? C.DependentTy : C.OverloadTy,
+ Dependent, Qualifier, QualifierRange,
+ Name, NameLoc, ADL, Overloaded, false);
+ }
+
+ static UnresolvedLookupExpr *Create(ASTContext &C,
+ bool Dependent,
+ NestedNameSpecifier *Qualifier,
+ SourceRange QualifierRange,
+ DeclarationName Name,
+ SourceLocation NameLoc,
+ bool ADL,
+ const TemplateArgumentListInfo &Args);
+
+ /// Computes whether an unresolved lookup on the given declarations
+ /// and optional template arguments is type- and value-dependent.
+ static bool ComputeDependence(NamedDecl * const *Begin,
+ NamedDecl * const *End,
+ const TemplateArgumentListInfo *Args);
+
+ void addDecl(NamedDecl *Decl) {
+ Results.addDecl(Decl);
+ }
+
+ typedef UnresolvedSet::iterator decls_iterator;
+ decls_iterator decls_begin() const { return Results.begin(); }
+ decls_iterator decls_end() const { return Results.end(); }
+
+ /// True if this declaration should be extended by
+ /// argument-dependent lookup.
+ bool requiresADL() const { return RequiresADL; }
+
+ /// True if this lookup is overloaded.
+ bool isOverloaded() const { return Overloaded; }
+
+ /// Fetches the name looked up.
+ DeclarationName getName() const { return Name; }
+
+ /// Gets the location of the name.
+ SourceLocation getNameLoc() const { return NameLoc; }
+
+ /// Fetches the nested-name qualifier, if one was given.
+ NestedNameSpecifier *getQualifier() const { return Qualifier; }
+
+ /// Fetches the range of the nested-name qualifier.
+ SourceRange getQualifierRange() const { return QualifierRange; }
+
+ /// Determines whether this lookup had explicit template arguments.
+ bool hasExplicitTemplateArgs() const { return HasExplicitTemplateArgs; }
+
+ // Note that, inconsistently with the explicit-template-argument AST
+ // nodes, users are *forbidden* from calling these methods on objects
+ // without explicit template arguments.
+
+ /// Gets a reference to the explicit template argument list.
+ const ExplicitTemplateArgumentList &getExplicitTemplateArgs() const {
+ assert(hasExplicitTemplateArgs());
+ return *reinterpret_cast<const ExplicitTemplateArgumentList*>(this + 1);
+ }
+
+ /// \brief Copies the template arguments (if present) into the given
+ /// structure.
+ void copyTemplateArgumentsInto(TemplateArgumentListInfo &List) const {
+ getExplicitTemplateArgs().copyInto(List);
+ }
+
+ SourceLocation getLAngleLoc() const {
+ return getExplicitTemplateArgs().LAngleLoc;
+ }
+
+ SourceLocation getRAngleLoc() const {
+ return getExplicitTemplateArgs().RAngleLoc;
+ }
+
+ TemplateArgumentLoc const *getTemplateArgs() const {
+ return getExplicitTemplateArgs().getTemplateArgs();
+ }
+
+ unsigned getNumTemplateArgs() const {
+ return getExplicitTemplateArgs().NumTemplateArgs;
+ }
+
+ virtual SourceRange getSourceRange() const {
+ SourceRange Range(NameLoc);
+ if (Qualifier) Range.setBegin(QualifierRange.getBegin());
+ if (hasExplicitTemplateArgs()) Range.setEnd(getRAngleLoc());
+ return Range;
+ }
+
+ virtual StmtIterator child_begin();
+ virtual StmtIterator child_end();
+
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == UnresolvedLookupExprClass;
+ }
+ static bool classof(const UnresolvedLookupExpr *) { return true; }
+};
+
/// \brief A qualified reference to a name whose declaration cannot
/// yet be resolved.
///
-/// UnresolvedDeclRefExpr is similar to eclRefExpr in that
+/// DependentScopeDeclRefExpr is similar to DeclRefExpr in that
/// it expresses a reference to a declaration such as
/// X<T>::value. The difference, however, is that an
-/// UnresolvedDeclRefExpr node is used only within C++ templates when
+/// DependentScopeDeclRefExpr node is used only within C++ templates when
/// the qualification (e.g., X<T>::) refers to a dependent type. In
/// this case, X<T>::value cannot resolve to a declaration because the
/// declaration will differ from on instantiation of X<T> to the
-/// next. Therefore, UnresolvedDeclRefExpr keeps track of the
+/// next. Therefore, DependentScopeDeclRefExpr keeps track of the
/// qualifier (X<T>::) and the name of the entity being referenced
/// ("value"). Such expressions will instantiate to a DeclRefExpr once the
/// declaration can be found.
-class UnresolvedDeclRefExpr : public Expr {
+class DependentScopeDeclRefExpr : public Expr {
/// The name of the entity we will be referencing.
DeclarationName Name;
@@ -1090,19 +1168,30 @@ class UnresolvedDeclRefExpr : public Expr {
/// \brief The nested-name-specifier that qualifies this unresolved
/// declaration name.
- NestedNameSpecifier *NNS;
+ NestedNameSpecifier *Qualifier;
- /// \brief Whether this expr is an address of (&) operand.
- /// FIXME: Stash this bit into NNS!
- bool IsAddressOfOperand;
+ /// \brief Whether the name includes explicit template arguments.
+ bool HasExplicitTemplateArgs;
+
+ DependentScopeDeclRefExpr(QualType T,
+ NestedNameSpecifier *Qualifier,
+ SourceRange QualifierRange,
+ DeclarationName Name,
+ SourceLocation NameLoc,
+ bool HasExplicitTemplateArgs)
+ : Expr(DependentScopeDeclRefExprClass, T, true, true),
+ Name(Name), Loc(NameLoc),
+ QualifierRange(QualifierRange), Qualifier(Qualifier),
+ HasExplicitTemplateArgs(HasExplicitTemplateArgs)
+ {}
public:
- UnresolvedDeclRefExpr(DeclarationName N, QualType T, SourceLocation L,
- SourceRange R, NestedNameSpecifier *NNS,
- bool IsAddressOfOperand)
- : Expr(UnresolvedDeclRefExprClass, T, true, true),
- Name(N), Loc(L), QualifierRange(R), NNS(NNS),
- IsAddressOfOperand(IsAddressOfOperand) { }
+ static DependentScopeDeclRefExpr *Create(ASTContext &C,
+ NestedNameSpecifier *Qualifier,
+ SourceRange QualifierRange,
+ DeclarationName Name,
+ SourceLocation NameLoc,
+ const TemplateArgumentListInfo *TemplateArgs = 0);
/// \brief Retrieve the name that this expression refers to.
DeclarationName getDeclName() const { return Name; }
@@ -1115,116 +1204,57 @@ public:
/// \brief Retrieve the nested-name-specifier that qualifies this
/// declaration.
- NestedNameSpecifier *getQualifier() const { return NNS; }
-
- /// \brief Retrieve whether this is an address of (&) operand.
-
- bool isAddressOfOperand() const { return IsAddressOfOperand; }
- virtual SourceRange getSourceRange() const {
- return SourceRange(QualifierRange.getBegin(), getLocation());
- }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == UnresolvedDeclRefExprClass;
- }
- static bool classof(const UnresolvedDeclRefExpr *) { return true; }
-
- virtual StmtIterator child_begin();
- virtual StmtIterator child_end();
-};
-
-/// \brief An expression that refers to a C++ template-id, such as
-/// @c isa<FunctionDecl>.
-class TemplateIdRefExpr : public Expr {
- /// \brief If this template-id was qualified-id, e.g., @c std::sort<int>,
- /// this nested name specifier contains the @c std::.
- NestedNameSpecifier *Qualifier;
-
- /// \brief If this template-id was a qualified-id, e.g., @c std::sort<int>,
- /// this covers the source code range of the @c std::.
- SourceRange QualifierRange;
-
- /// \brief The actual template to which this template-id refers.
- TemplateName Template;
-
- /// \brief The source location of the template name.
- SourceLocation TemplateNameLoc;
-
- /// \brief The source location of the left angle bracket ('<');
- SourceLocation LAngleLoc;
-
- /// \brief The source location of the right angle bracket ('>');
- SourceLocation RAngleLoc;
-
- /// \brief The number of template arguments in TemplateArgs.
- unsigned NumTemplateArgs;
-
- TemplateIdRefExpr(QualType T,
- NestedNameSpecifier *Qualifier, SourceRange QualifierRange,
- TemplateName Template, SourceLocation TemplateNameLoc,
- SourceLocation LAngleLoc,
- const TemplateArgumentLoc *TemplateArgs,
- unsigned NumTemplateArgs,
- SourceLocation RAngleLoc);
-
- virtual void DoDestroy(ASTContext &Context);
-
-public:
- static TemplateIdRefExpr *
- Create(ASTContext &Context, QualType T,
- NestedNameSpecifier *Qualifier, SourceRange QualifierRange,
- TemplateName Template, SourceLocation TemplateNameLoc,
- SourceLocation LAngleLoc, const TemplateArgumentLoc *TemplateArgs,
- unsigned NumTemplateArgs, SourceLocation RAngleLoc);
-
- /// \brief Retrieve the nested name specifier used to qualify the name of
- /// this template-id, e.g., the "std::sort" in @c std::sort<int>, or NULL
- /// if this template-id was an unqualified-id.
NestedNameSpecifier *getQualifier() const { return Qualifier; }
- /// \brief Retrieve the source range describing the nested name specifier
- /// used to qualified the name of this template-id, if the name was qualified.
- SourceRange getQualifierRange() const { return QualifierRange; }
+ /// Determines whether this lookup had explicit template arguments.
+ bool hasExplicitTemplateArgs() const { return HasExplicitTemplateArgs; }
- /// \brief Retrieve the name of the template referenced, e.g., "sort" in
- /// @c std::sort<int>;
- TemplateName getTemplateName() const { return Template; }
+ // Note that, inconsistently with the explicit-template-argument AST
+ // nodes, users are *forbidden* from calling these methods on objects
+ // without explicit template arguments.
- /// \brief Retrieve the location of the name of the template referenced, e.g.,
- /// the location of "sort" in @c std::sort<int>.
- SourceLocation getTemplateNameLoc() const { return TemplateNameLoc; }
+ /// Gets a reference to the explicit template argument list.
+ const ExplicitTemplateArgumentList &getExplicitTemplateArgs() const {
+ assert(hasExplicitTemplateArgs());
+ return *reinterpret_cast<const ExplicitTemplateArgumentList*>(this + 1);
+ }
- /// \brief Retrieve the location of the left angle bracket following the
- /// template name ('<').
- SourceLocation getLAngleLoc() const { return LAngleLoc; }
+ /// \brief Copies the template arguments (if present) into the given
+ /// structure.
+ void copyTemplateArgumentsInto(TemplateArgumentListInfo &List) const {
+ getExplicitTemplateArgs().copyInto(List);
+ }
+
+ SourceLocation getLAngleLoc() const {
+ return getExplicitTemplateArgs().LAngleLoc;
+ }
- /// \brief Retrieve the template arguments provided as part of this
- /// template-id.
- const TemplateArgumentLoc *getTemplateArgs() const {
- return reinterpret_cast<const TemplateArgumentLoc *>(this + 1);
+ SourceLocation getRAngleLoc() const {
+ return getExplicitTemplateArgs().RAngleLoc;
}
- /// \brief Retrieve the number of template arguments provided as part of this
- /// template-id.
- unsigned getNumTemplateArgs() const { return NumTemplateArgs; }
+ TemplateArgumentLoc const *getTemplateArgs() const {
+ return getExplicitTemplateArgs().getTemplateArgs();
+ }
- /// \brief Retrieve the location of the right angle bracket following the
- /// template arguments ('>').
- SourceLocation getRAngleLoc() const { return RAngleLoc; }
+ unsigned getNumTemplateArgs() const {
+ return getExplicitTemplateArgs().NumTemplateArgs;
+ }
virtual SourceRange getSourceRange() const {
- return SourceRange(Qualifier? QualifierRange.getBegin() : TemplateNameLoc,
- RAngleLoc);
+ SourceRange Range(QualifierRange.getBegin(), getLocation());
+ if (hasExplicitTemplateArgs())
+ Range.setEnd(getRAngleLoc());
+ return Range;
}
- // Iterators
- virtual child_iterator child_begin();
- virtual child_iterator child_end();
-
static bool classof(const Stmt *T) {
- return T->getStmtClass() == TemplateIdRefExprClass;
+ return T->getStmtClass() == DependentScopeDeclRefExprClass;
}
- static bool classof(const TemplateIdRefExpr *) { return true; }
+ static bool classof(const DependentScopeDeclRefExpr *) { return true; }
+
+ virtual StmtIterator child_begin();
+ virtual StmtIterator child_end();
};
class CXXExprWithTemporaries : public Expr {
@@ -1377,10 +1407,10 @@ public:
virtual child_iterator child_end();
};
-/// \brief Represents a C++ member access expression where the actual member
-/// referenced could not be resolved, e.g., because the base expression or the
-/// member name was dependent.
-class CXXUnresolvedMemberExpr : public Expr {
+/// \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.
+class CXXDependentScopeMemberExpr : public Expr {
/// \brief The expression for the base pointer or class reference,
/// e.g., the \c x in x.f.
Stmt *Base;
@@ -1408,7 +1438,7 @@ class CXXUnresolvedMemberExpr : public Expr {
///
/// FIXME: This member, along with the Qualifier and QualifierRange, could
/// be stuck into a structure that is optionally allocated at the end of
- /// the CXXUnresolvedMemberExpr, to save space in the common case.
+ /// the CXXDependentScopeMemberExpr, to save space in the common case.
NamedDecl *FirstQualifierFoundInScope;
/// \brief The member to which this member expression refers, which
@@ -1431,11 +1461,11 @@ class CXXUnresolvedMemberExpr : public Expr {
/// \brief Retrieve the explicit template argument list that followed the
/// member template name, if any.
const ExplicitTemplateArgumentList *getExplicitTemplateArgumentList() const {
- return const_cast<CXXUnresolvedMemberExpr *>(this)
+ return const_cast<CXXDependentScopeMemberExpr *>(this)
->getExplicitTemplateArgumentList();
}
- CXXUnresolvedMemberExpr(ASTContext &C,
+ CXXDependentScopeMemberExpr(ASTContext &C,
Expr *Base, bool IsArrow,
SourceLocation OperatorLoc,
NestedNameSpecifier *Qualifier,
@@ -1443,14 +1473,10 @@ class CXXUnresolvedMemberExpr : public Expr {
NamedDecl *FirstQualifierFoundInScope,
DeclarationName Member,
SourceLocation MemberLoc,
- bool HasExplicitTemplateArgs,
- SourceLocation LAngleLoc,
- const TemplateArgumentLoc *TemplateArgs,
- unsigned NumTemplateArgs,
- SourceLocation RAngleLoc);
+ const TemplateArgumentListInfo *TemplateArgs);
public:
- CXXUnresolvedMemberExpr(ASTContext &C,
+ CXXDependentScopeMemberExpr(ASTContext &C,
Expr *Base, bool IsArrow,
SourceLocation OperatorLoc,
NestedNameSpecifier *Qualifier,
@@ -1458,14 +1484,14 @@ public:
NamedDecl *FirstQualifierFoundInScope,
DeclarationName Member,
SourceLocation MemberLoc)
- : Expr(CXXUnresolvedMemberExprClass, C.DependentTy, true, true),
+ : Expr(CXXDependentScopeMemberExprClass, C.DependentTy, true, true),
Base(Base), IsArrow(IsArrow), HasExplicitTemplateArgumentList(false),
OperatorLoc(OperatorLoc),
Qualifier(Qualifier), QualifierRange(QualifierRange),
FirstQualifierFoundInScope(FirstQualifierFoundInScope),
Member(Member), MemberLoc(MemberLoc) { }
- static CXXUnresolvedMemberExpr *
+ static CXXDependentScopeMemberExpr *
Create(ASTContext &C,
Expr *Base, bool IsArrow,
SourceLocation OperatorLoc,
@@ -1474,11 +1500,7 @@ public:
NamedDecl *FirstQualifierFoundInScope,
DeclarationName Member,
SourceLocation MemberLoc,
- bool HasExplicitTemplateArgs,
- SourceLocation LAngleLoc,
- const TemplateArgumentLoc *TemplateArgs,
- unsigned NumTemplateArgs,
- SourceLocation RAngleLoc);
+ const TemplateArgumentListInfo *TemplateArgs);
/// \brief Retrieve the base object of this member expressions,
/// e.g., the \c x in \c x.m.
@@ -1529,10 +1551,17 @@ public:
/// \brief Determines whether this member expression actually had a C++
/// template argument list explicitly specified, e.g., x.f<int>.
- bool hasExplicitTemplateArgumentList() {
+ bool hasExplicitTemplateArgumentList() const {
return HasExplicitTemplateArgumentList;
}
+ /// \brief Copies the template arguments (if present) into the given
+ /// structure.
+ void copyTemplateArgumentsInto(TemplateArgumentListInfo &List) const {
+ if (hasExplicitTemplateArgumentList())
+ getExplicitTemplateArgumentList()->copyInto(List);
+ }
+
/// \brief Retrieve the location of the left angle bracket following the
/// member name ('<'), if any.
SourceLocation getLAngleLoc() const {
@@ -1579,9 +1608,182 @@ public:
}
static bool classof(const Stmt *T) {
- return T->getStmtClass() == CXXUnresolvedMemberExprClass;
+ return T->getStmtClass() == CXXDependentScopeMemberExprClass;
+ }
+ static bool classof(const CXXDependentScopeMemberExpr *) { return true; }
+
+ // Iterators
+ virtual child_iterator child_begin();
+ virtual child_iterator child_end();
+};
+
+/// \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.
+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.
+ Stmt *Base;
+
+ /// \brief Whether this member expression used the '->' operator or
+ /// the '.' operator.
+ bool IsArrow : 1;
+
+ /// \brief Whether the lookup results contain an unresolved using
+ /// declaration.
+ bool HasUnresolvedUsing : 1;
+
+ /// \brief Whether this member expression has explicitly-specified template
+ /// arguments.
+ bool HasExplicitTemplateArgs : 1;
+
+ /// \brief The location of the '->' or '.' operator.
+ SourceLocation OperatorLoc;
+
+ /// \brief The nested-name-specifier that precedes the member name, if any.
+ NestedNameSpecifier *Qualifier;
+
+ /// \brief The source range covering the nested name specifier.
+ SourceRange QualifierRange;
+
+ /// \brief The member to which this member expression refers, which
+ /// can be a name or an overloaded operator.
+ DeclarationName MemberName;
+
+ /// \brief The location of the member name.
+ SourceLocation MemberLoc;
+
+ /// \brief Retrieve the explicit template argument list that followed the
+ /// member template name.
+ ExplicitTemplateArgumentList *getExplicitTemplateArgs() {
+ assert(HasExplicitTemplateArgs);
+ return reinterpret_cast<ExplicitTemplateArgumentList *>(this + 1);
+ }
+
+ /// \brief Retrieve the explicit template argument list that followed the
+ /// member template name, if any.
+ const ExplicitTemplateArgumentList *getExplicitTemplateArgs() const {
+ return const_cast<UnresolvedMemberExpr*>(this)->getExplicitTemplateArgs();
+ }
+
+ UnresolvedMemberExpr(QualType T, bool Dependent,
+ bool HasUnresolvedUsing,
+ Expr *Base, bool IsArrow,
+ SourceLocation OperatorLoc,
+ NestedNameSpecifier *Qualifier,
+ SourceRange QualifierRange,
+ DeclarationName Member,
+ SourceLocation MemberLoc,
+ const TemplateArgumentListInfo *TemplateArgs);
+
+public:
+ static UnresolvedMemberExpr *
+ Create(ASTContext &C, bool Dependent, bool HasUnresolvedUsing,
+ Expr *Base, bool IsArrow,
+ SourceLocation OperatorLoc,
+ NestedNameSpecifier *Qualifier,
+ SourceRange QualifierRange,
+ DeclarationName Member,
+ SourceLocation MemberLoc,
+ const TemplateArgumentListInfo *TemplateArgs);
+
+ /// Adds a declaration to the unresolved set. By assumption, all of
+ /// these happen at initialization time and properties like
+ /// 'Dependent' and 'HasUnresolvedUsing' take them into account.
+ void addDecl(NamedDecl *Decl) {
+ Results.addDecl(Decl);
+ }
+
+ typedef UnresolvedSet::iterator decls_iterator;
+ decls_iterator decls_begin() const { return Results.begin(); }
+ decls_iterator decls_end() const { return Results.end(); }
+
+ unsigned getNumDecls() const { return Results.size(); }
+
+ /// \brief Retrieve the base object of this member expressions,
+ /// e.g., the \c x in \c x.m.
+ Expr *getBase() { return cast<Expr>(Base); }
+ void setBase(Expr *E) { Base = E; }
+
+ /// \brief Determine whether this member expression used the '->'
+ /// operator; otherwise, it used the '.' operator.
+ bool isArrow() const { return IsArrow; }
+ void setArrow(bool A) { IsArrow = A; }
+
+ /// \brief Retrieve the location of the '->' or '.' operator.
+ SourceLocation getOperatorLoc() const { return OperatorLoc; }
+ void setOperatorLoc(SourceLocation L) { OperatorLoc = L; }
+
+ /// \brief Retrieve the nested-name-specifier that qualifies the member
+ /// name.
+ NestedNameSpecifier *getQualifier() const { return Qualifier; }
+
+ /// \brief Retrieve the source range covering the nested-name-specifier
+ /// that qualifies the member name.
+ SourceRange getQualifierRange() const { return QualifierRange; }
+
+ /// \brief Retrieve the name of the member that this expression
+ /// refers to.
+ DeclarationName getMemberName() const { return MemberName; }
+ void setMemberName(DeclarationName N) { MemberName = N; }
+
+ // \brief Retrieve the location of the name of the member that this
+ // expression refers to.
+ SourceLocation getMemberLoc() const { return MemberLoc; }
+ void setMemberLoc(SourceLocation L) { MemberLoc = L; }
+
+ /// \brief Determines whether this member expression actually had a C++
+ /// template argument list explicitly specified, e.g., x.f<int>.
+ bool hasExplicitTemplateArgs() const {
+ return HasExplicitTemplateArgs;
+ }
+
+ /// \brief Copies the template arguments into the given structure.
+ void copyTemplateArgumentsInto(TemplateArgumentListInfo &List) const {
+ getExplicitTemplateArgs()->copyInto(List);
+ }
+
+ /// \brief Retrieve the location of the left angle bracket following
+ /// the member name ('<').
+ SourceLocation getLAngleLoc() const {
+ return getExplicitTemplateArgs()->LAngleLoc;
+ }
+
+ /// \brief Retrieve the template arguments provided as part of this
+ /// template-id.
+ const TemplateArgumentLoc *getTemplateArgs() const {
+ return getExplicitTemplateArgs()->getTemplateArgs();
+ }
+
+ /// \brief Retrieve the number of template arguments provided as
+ /// part of this template-id.
+ unsigned getNumTemplateArgs() const {
+ return getExplicitTemplateArgs()->NumTemplateArgs;
+ }
+
+ /// \brief Retrieve the location of the right angle bracket
+ /// following the template arguments ('>').
+ SourceLocation getRAngleLoc() const {
+ return getExplicitTemplateArgs()->RAngleLoc;
+ }
+
+ virtual SourceRange getSourceRange() const {
+ SourceRange Range = Base->getSourceRange();
+ if (hasExplicitTemplateArgs())
+ Range.setEnd(getRAngleLoc());
+ else
+ Range.setEnd(MemberLoc);
+ return Range;
+ }
+
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == UnresolvedMemberExprClass;
}
- static bool classof(const CXXUnresolvedMemberExpr *) { return true; }
+ static bool classof(const UnresolvedMemberExpr *) { return true; }
// Iterators
virtual child_iterator child_begin();
diff --git a/include/clang/AST/RecordLayout.h b/include/clang/AST/RecordLayout.h
index 9b1c640..5d2973e 100644
--- a/include/clang/AST/RecordLayout.h
+++ b/include/clang/AST/RecordLayout.h
@@ -47,6 +47,59 @@ class ASTRecordLayout {
// FieldCount - Number of fields.
unsigned FieldCount;
+public:
+ /// PrimaryBaseInfo - Contains info about a primary base.
+ struct PrimaryBaseInfo {
+ PrimaryBaseInfo() {}
+
+ PrimaryBaseInfo(const CXXRecordDecl *Base, bool IsVirtual)
+ : Value(Base, IsVirtual) {}
+
+ /// Value - Points to the primary base. The single-bit value
+ /// will be non-zero when the primary base is virtual.
+ llvm::PointerIntPair<const CXXRecordDecl *, 1, bool> Value;
+
+ /// getBase - Returns the primary base.
+ const CXXRecordDecl *getBase() const { return Value.getPointer(); }
+
+ /// isVirtual - Returns whether the primary base is virtual or not.
+ bool isVirtual() const { return Value.getInt(); }
+
+ friend bool operator==(const PrimaryBaseInfo &X, const PrimaryBaseInfo &Y) {
+ return X.Value == Y.Value;
+ }
+ };
+
+ /// primary_base_info_iterator - An iterator for iterating the primary base
+ /// class chain.
+ class primary_base_info_iterator {
+ /// Current - The current base class info.
+ PrimaryBaseInfo Current;
+
+ public:
+ primary_base_info_iterator() {}
+ primary_base_info_iterator(PrimaryBaseInfo Info) : Current(Info) {}
+
+ const PrimaryBaseInfo &operator*() const { return Current; }
+
+ primary_base_info_iterator& operator++() {
+ const CXXRecordDecl *RD = Current.getBase();
+ Current = RD->getASTContext().getASTRecordLayout(RD).getPrimaryBaseInfo();
+ return *this;
+ }
+
+ friend bool operator==(const primary_base_info_iterator &X,
+ const primary_base_info_iterator &Y) {
+ return X.Current == Y.Current;
+ }
+ friend bool operator!=(const primary_base_info_iterator &X,
+ const primary_base_info_iterator &Y) {
+ return !(X == Y);
+ }
+ };
+
+private:
+ /// CXXRecordLayoutInfo - Contains C++ specific layout information.
struct CXXRecordLayoutInfo {
/// NonVirtualSize - The non-virtual size (in bits) of an object, which is
/// the size of the object without virtual bases.
@@ -56,11 +109,9 @@ class ASTRecordLayout {
/// which is the alignment of the object without virtual bases.
uint64_t NonVirtualAlign;
- /// PrimaryBase - The primary base for our vtable.
- const CXXRecordDecl *PrimaryBase;
- /// PrimaryBase - Wether or not the primary base was a virtual base.
- bool PrimaryBaseWasVirtual;
-
+ /// PrimaryBase - The primary base info for this record.
+ PrimaryBaseInfo PrimaryBase;
+
/// BaseOffsets - Contains a map from base classes to their offset.
/// FIXME: This should really use a SmallPtrMap, once we have one in LLVM :)
llvm::DenseMap<const CXXRecordDecl *, uint64_t> BaseOffsets;
@@ -68,6 +119,13 @@ class ASTRecordLayout {
/// 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
@@ -92,11 +150,12 @@ class ASTRecordLayout {
ASTRecordLayout(uint64_t size, unsigned alignment, uint64_t datasize,
const uint64_t *fieldoffsets, unsigned fieldcount,
uint64_t nonvirtualsize, unsigned nonvirtualalign,
- const CXXRecordDecl *PB, bool PBVirtual,
+ const PrimaryBaseInfo &PrimaryBase,
const std::pair<const CXXRecordDecl *, uint64_t> *bases,
unsigned numbases,
const std::pair<const CXXRecordDecl *, uint64_t> *vbases,
- unsigned numvbases)
+ unsigned numvbases,
+ const CXXMethodDecl *KeyFunction)
: Size(size), DataSize(datasize), FieldOffsets(0), Alignment(alignment),
FieldCount(fieldcount), CXXInfo(new CXXRecordLayoutInfo) {
if (FieldCount > 0) {
@@ -105,14 +164,14 @@ class ASTRecordLayout {
FieldOffsets[i] = fieldoffsets[i];
}
- CXXInfo->PrimaryBase = PB;
- CXXInfo->PrimaryBaseWasVirtual = PBVirtual;
+ CXXInfo->PrimaryBase = PrimaryBase;
CXXInfo->NonVirtualSize = nonvirtualsize;
CXXInfo->NonVirtualAlign = nonvirtualalign;
for (unsigned i = 0; i != numbases; ++i)
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() {
@@ -162,17 +221,21 @@ public:
return CXXInfo->NonVirtualAlign;
}
- /// getPrimaryBase - Get the primary base.
- const CXXRecordDecl *getPrimaryBase() const {
+ /// getPrimaryBaseInfo - Get the primary base info.
+ const PrimaryBaseInfo &getPrimaryBaseInfo() const {
assert(CXXInfo && "Record layout does not have C++ specific info!");
return CXXInfo->PrimaryBase;
}
- /// getPrimaryBaseWasVirtual - Indicates if the primary base was virtual.
- bool getPrimaryBaseWasVirtual() const {
- assert(CXXInfo && "Record layout does not have C++ specific info!");
- return CXXInfo->PrimaryBaseWasVirtual;
+ // FIXME: Migrate off of this function and use getPrimaryBaseInfo directly.
+ const CXXRecordDecl *getPrimaryBase() const {
+ return getPrimaryBaseInfo().getBase();
+ }
+
+ // FIXME: Migrate off of this function and use getPrimaryBaseInfo directly.
+ bool getPrimaryBaseWasVirtual() const {
+ return getPrimaryBaseInfo().isVirtual();
}
/// getBaseClassOffset - Get the offset, in bits, for the given base class.
@@ -190,6 +253,25 @@ 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!");
+
+ return primary_base_info_iterator(getPrimaryBaseInfo());
+ }
+
+ primary_base_info_iterator primary_base_end() const {
+ assert(CXXInfo && "Record layout does not have C++ specific info!");
+
+ return primary_base_info_iterator();
+ }
};
} // end namespace clang
diff --git a/include/clang/AST/Redeclarable.h b/include/clang/AST/Redeclarable.h
index 8679323..01f4b29 100644
--- a/include/clang/AST/Redeclarable.h
+++ b/include/clang/AST/Redeclarable.h
@@ -15,6 +15,7 @@
#define LLVM_CLANG_AST_REDECLARABLE_H
#include "llvm/ADT/PointerIntPair.h"
+#include "llvm/Support/Casting.h"
#include <iterator>
namespace clang {
@@ -92,6 +93,11 @@ public:
}
/// \brief Returns the most recent (re)declaration of this declaration.
+ decl_type *getMostRecentDeclaration() {
+ return getFirstDeclaration()->RedeclLink.getNext();
+ }
+
+ /// \brief Returns the most recent (re)declaration of this declaration.
const decl_type *getMostRecentDeclaration() const {
return getFirstDeclaration()->RedeclLink.getNext();
}
@@ -102,8 +108,11 @@ public:
decl_type *First;
if (PrevDecl) {
- // Point to previous.
- RedeclLink = PreviousDeclLink(PrevDecl);
+ // Point to previous. Make sure that this is actually the most recent
+ // redeclaration, or we can build invalid chains. If the most recent
+ // redeclaration is invalid, it won't be PrevDecl, but we want it anyway.
+ RedeclLink = PreviousDeclLink(llvm::cast<decl_type>(
+ PrevDecl->getMostRecentDeclaration()));
First = PrevDecl->getFirstDeclaration();
assert(First->RedeclLink.NextIsLatest() && "Expected first");
} else {
diff --git a/include/clang/AST/Stmt.h b/include/clang/AST/Stmt.h
index 411f215e..d6f6a83 100644
--- a/include/clang/AST/Stmt.h
+++ b/include/clang/AST/Stmt.h
@@ -171,6 +171,14 @@ public:
}
virtual ~Stmt() {}
+#ifndef NDEBUG
+ /// \brief True if this statement's refcount is in a valid state.
+ /// Should be used only in assertions.
+ bool isRetained() const {
+ return (RefCount >= 1);
+ }
+#endif
+
/// \brief Destroy the current statement and its children.
void Destroy(ASTContext &Ctx) {
assert(RefCount >= 1);
@@ -203,7 +211,7 @@ public:
// global temp stats (until we have a per-module visitor)
static void addStmtClass(const StmtClass s);
- static bool CollectingStats(bool enable=false);
+ static bool CollectingStats(bool Enable = false);
static void PrintStats();
/// dump - This does a local dump of the specified AST fragment. It dumps the
@@ -604,22 +612,36 @@ public:
class IfStmt : public Stmt {
enum { COND, THEN, ELSE, END_EXPR };
Stmt* SubExprs[END_EXPR];
+
+ /// \brief If non-NULL, the declaration in the "if" statement.
+ VarDecl *Var;
+
SourceLocation IfLoc;
SourceLocation ElseLoc;
+
public:
- IfStmt(SourceLocation IL, Expr *cond, Stmt *then,
+ IfStmt(SourceLocation IL, VarDecl *Var, Expr *cond, Stmt *then,
SourceLocation EL = SourceLocation(), Stmt *elsev = 0)
- : Stmt(IfStmtClass) {
+ : Stmt(IfStmtClass), Var(Var), IfLoc(IL), ElseLoc(EL) {
SubExprs[COND] = reinterpret_cast<Stmt*>(cond);
SubExprs[THEN] = then;
SubExprs[ELSE] = elsev;
- IfLoc = IL;
- ElseLoc = EL;
}
/// \brief Build an empty if/then/else statement
explicit IfStmt(EmptyShell Empty) : Stmt(IfStmtClass, Empty) { }
+ /// \brief Retrieve the variable declared in this "if" statement, if any.
+ ///
+ /// In the following example, "x" is the condition variable.
+ /// \code
+ /// if (int x = foo()) {
+ /// printf("x is %d", x);
+ /// }
+ /// \endcode
+ VarDecl *getConditionVariable() const { return Var; }
+ void setConditionVariable(VarDecl *V) { Var = V; }
+
const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);}
void setCond(Expr *E) { SubExprs[COND] = reinterpret_cast<Stmt *>(E); }
const Stmt *getThen() const { return SubExprs[THEN]; }
@@ -658,6 +680,7 @@ public:
class SwitchStmt : public Stmt {
enum { COND, BODY, END_EXPR };
Stmt* SubExprs[END_EXPR];
+ VarDecl *Var;
// This points to a linked list of case and default statements.
SwitchCase *FirstCase;
SourceLocation SwitchLoc;
@@ -666,14 +689,28 @@ protected:
virtual void DoDestroy(ASTContext &Ctx);
public:
- SwitchStmt(Expr *cond) : Stmt(SwitchStmtClass), FirstCase(0) {
- SubExprs[COND] = reinterpret_cast<Stmt*>(cond);
- SubExprs[BODY] = NULL;
- }
+ SwitchStmt(VarDecl *Var, Expr *cond)
+ : Stmt(SwitchStmtClass), Var(Var), FirstCase(0)
+ {
+ SubExprs[COND] = reinterpret_cast<Stmt*>(cond);
+ SubExprs[BODY] = NULL;
+ }
/// \brief Build a empty switch statement.
explicit SwitchStmt(EmptyShell Empty) : Stmt(SwitchStmtClass, Empty) { }
+ /// \brief Retrieve the variable declared in this "switch" statement, if any.
+ ///
+ /// In the following example, "x" is the condition variable.
+ /// \code
+ /// switch (int x = foo()) {
+ /// case 0: break;
+ /// // ...
+ /// }
+ /// \endcode
+ VarDecl *getConditionVariable() const { return Var; }
+ void setConditionVariable(VarDecl *V) { Var = V; }
+
const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);}
const Stmt *getBody() const { return SubExprs[BODY]; }
const SwitchCase *getSwitchCaseList() const { return FirstCase; }
@@ -721,10 +758,13 @@ public:
///
class WhileStmt : public Stmt {
enum { COND, BODY, END_EXPR };
+ VarDecl *Var;
Stmt* SubExprs[END_EXPR];
SourceLocation WhileLoc;
public:
- WhileStmt(Expr *cond, Stmt *body, SourceLocation WL) : Stmt(WhileStmtClass) {
+ WhileStmt(VarDecl *Var, Expr *cond, Stmt *body, SourceLocation WL)
+ : Stmt(WhileStmtClass), Var(Var)
+ {
SubExprs[COND] = reinterpret_cast<Stmt*>(cond);
SubExprs[BODY] = body;
WhileLoc = WL;
@@ -733,6 +773,17 @@ public:
/// \brief Build an empty while statement.
explicit WhileStmt(EmptyShell Empty) : Stmt(WhileStmtClass, Empty) { }
+ /// \brief Retrieve the variable declared in this "while" statement, if any.
+ ///
+ /// In the following example, "x" is the condition variable.
+ /// \code
+ /// while (int x = random()) {
+ /// // ...
+ /// }
+ /// \endcode
+ VarDecl *getConditionVariable() const { return Var; }
+ void setConditionVariable(VarDecl *V) { Var = V; }
+
Expr *getCond() { return reinterpret_cast<Expr*>(SubExprs[COND]); }
const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);}
void setCond(Expr *E) { SubExprs[COND] = reinterpret_cast<Stmt*>(E); }
@@ -812,26 +863,38 @@ public:
class ForStmt : public Stmt {
enum { INIT, COND, INC, BODY, END_EXPR };
Stmt* SubExprs[END_EXPR]; // SubExprs[INIT] is an expression or declstmt.
+ VarDecl *CondVar;
SourceLocation ForLoc;
SourceLocation LParenLoc, RParenLoc;
public:
- ForStmt(Stmt *Init, Expr *Cond, Expr *Inc, Stmt *Body, SourceLocation FL,
- SourceLocation LP, SourceLocation RP)
- : Stmt(ForStmtClass) {
+ ForStmt(Stmt *Init, Expr *Cond, VarDecl *CondVar, Expr *Inc, Stmt *Body,
+ SourceLocation FL, SourceLocation LP, SourceLocation RP)
+ : Stmt(ForStmtClass), CondVar(CondVar), ForLoc(FL), LParenLoc(LP),
+ RParenLoc(RP)
+ {
SubExprs[INIT] = Init;
SubExprs[COND] = reinterpret_cast<Stmt*>(Cond);
SubExprs[INC] = reinterpret_cast<Stmt*>(Inc);
SubExprs[BODY] = Body;
- ForLoc = FL;
- LParenLoc = LP;
- RParenLoc = RP;
}
/// \brief Build an empty for statement.
explicit ForStmt(EmptyShell Empty) : Stmt(ForStmtClass, Empty) { }
Stmt *getInit() { return SubExprs[INIT]; }
+
+ /// \brief Retrieve the variable declared in this "for" statement, if any.
+ ///
+ /// In the following example, "y" is the condition variable.
+ /// \code
+ /// for (int x = random(); int y = mangle(x); ++x) {
+ /// // ...
+ /// }
+ /// \endcode
+ VarDecl *getConditionVariable() const { return CondVar; }
+ void setConditionVariable(VarDecl *V) { CondVar = V; }
+
Expr *getCond() { return reinterpret_cast<Expr*>(SubExprs[COND]); }
Expr *getInc() { return reinterpret_cast<Expr*>(SubExprs[INC]); }
Stmt *getBody() { return SubExprs[BODY]; }
diff --git a/include/clang/AST/StmtCXX.h b/include/clang/AST/StmtCXX.h
index 28fe348..64eea24 100644
--- a/include/clang/AST/StmtCXX.h
+++ b/include/clang/AST/StmtCXX.h
@@ -42,9 +42,9 @@ public:
}
SourceLocation getCatchLoc() const { return CatchLoc; }
- VarDecl *getExceptionDecl() { return ExceptionDecl; }
- QualType getCaughtType();
- Stmt *getHandlerBlock() { return HandlerBlock; }
+ VarDecl *getExceptionDecl() const { return ExceptionDecl; }
+ QualType getCaughtType() const;
+ Stmt *getHandlerBlock() const { return HandlerBlock; }
static bool classof(const Stmt *T) {
return T->getStmtClass() == CXXCatchStmtClass;
diff --git a/include/clang/AST/StmtNodes.def b/include/clang/AST/StmtNodes.def
index 034029a..7102336 100644
--- a/include/clang/AST/StmtNodes.def
+++ b/include/clang/AST/StmtNodes.def
@@ -121,20 +121,19 @@ EXPR(CXXThisExpr , Expr)
EXPR(CXXThrowExpr , Expr)
EXPR(CXXDefaultArgExpr , Expr)
EXPR(CXXZeroInitValueExpr , Expr)
-EXPR(CXXConditionDeclExpr , DeclRefExpr)
EXPR(CXXNewExpr , Expr)
EXPR(CXXDeleteExpr , Expr)
EXPR(CXXPseudoDestructorExpr, Expr)
-EXPR(UnresolvedFunctionNameExpr , Expr)
+EXPR(UnresolvedLookupExpr , Expr)
EXPR(UnaryTypeTraitExpr , Expr)
-EXPR(UnresolvedDeclRefExpr , Expr)
-EXPR(TemplateIdRefExpr , Expr)
+EXPR(DependentScopeDeclRefExpr , Expr)
EXPR(CXXConstructExpr , Expr)
EXPR(CXXBindTemporaryExpr , Expr)
EXPR(CXXExprWithTemporaries , Expr)
EXPR(CXXTemporaryObjectExpr , CXXConstructExpr)
EXPR(CXXUnresolvedConstructExpr, Expr)
-EXPR(CXXUnresolvedMemberExpr, Expr)
+EXPR(CXXDependentScopeMemberExpr, Expr)
+EXPR(UnresolvedMemberExpr , Expr)
// Obj-C Expressions.
EXPR(ObjCStringLiteral , Expr)
diff --git a/include/clang/AST/TemplateBase.h b/include/clang/AST/TemplateBase.h
index 6db0958..b46b3dc 100644
--- a/include/clang/AST/TemplateBase.h
+++ b/include/clang/AST/TemplateBase.h
@@ -16,6 +16,7 @@
#define LLVM_CLANG_AST_TEMPLATEBASE_H
#include "llvm/ADT/APSInt.h"
+#include "llvm/ADT/SmallVector.h"
#include "llvm/Support/ErrorHandling.h"
#include "clang/AST/Type.h"
#include "clang/AST/TemplateName.h"
@@ -437,6 +438,41 @@ public:
}
};
+/// A convenient class for passing around template argument
+/// information. Designed to be passed by reference.
+class TemplateArgumentListInfo {
+ llvm::SmallVector<TemplateArgumentLoc, 8> Arguments;
+ SourceLocation LAngleLoc;
+ SourceLocation RAngleLoc;
+
+public:
+ TemplateArgumentListInfo() {}
+
+ TemplateArgumentListInfo(SourceLocation LAngleLoc,
+ SourceLocation RAngleLoc)
+ : LAngleLoc(LAngleLoc), RAngleLoc(RAngleLoc) {}
+
+ SourceLocation getLAngleLoc() const { return LAngleLoc; }
+ SourceLocation getRAngleLoc() const { return RAngleLoc; }
+
+ void setLAngleLoc(SourceLocation Loc) { LAngleLoc = Loc; }
+ void setRAngleLoc(SourceLocation Loc) { RAngleLoc = Loc; }
+
+ unsigned size() const { return Arguments.size(); }
+
+ const TemplateArgumentLoc *getArgumentArray() const {
+ return Arguments.data();
+ }
+
+ const TemplateArgumentLoc &operator[](unsigned I) const {
+ return Arguments[I];
+ }
+
+ void addArgument(const TemplateArgumentLoc &Loc) {
+ Arguments.push_back(Loc);
+ }
+};
+
}
#endif
diff --git a/include/clang/AST/Type.h b/include/clang/AST/Type.h
index c28bafe..349487f 100644
--- a/include/clang/AST/Type.h
+++ b/include/clang/AST/Type.h
@@ -82,6 +82,7 @@ namespace clang {
class StmtIteratorBase;
class TemplateArgument;
class TemplateArgumentLoc;
+ class TemplateArgumentListInfo;
class QualifiedNameType;
struct PrintingPolicy;
@@ -859,6 +860,7 @@ public:
bool isObjCQualifiedClassType() const; // Class<foo>
bool isObjCIdType() const; // id
bool isObjCClassType() const; // Class
+ bool isObjCSelType() const; // Class
bool isObjCBuiltinType() const; // 'id' or 'Class'
bool isTemplateTypeParmType() const; // C++ template type parameter
bool isNullPtrType() const; // C++0x nullptr_t
@@ -1000,7 +1002,8 @@ public:
UndeducedAuto, // In C++0x, this represents the type of an auto variable
// that has not been deduced yet.
ObjCId, // This represents the ObjC 'id' type.
- ObjCClass // This represents the ObjC 'Class' type.
+ ObjCClass, // This represents the ObjC 'Class' type.
+ ObjCSel // This represents the ObjC 'SEL' type.
};
private:
Kind TypeKind;
@@ -1457,21 +1460,27 @@ public:
/// DependentSizedArrayType - This type represents an array type in
/// C++ whose size is a value-dependent expression. For example:
-/// @code
+///
+/// \code
/// template<typename T, int Size>
/// class array {
/// T data[Size];
/// };
-/// @endcode
+/// \endcode
+///
/// For these types, we won't actually know what the array bound is
/// until template instantiation occurs, at which point this will
/// become either a ConstantArrayType or a VariableArrayType.
class DependentSizedArrayType : public ArrayType {
ASTContext &Context;
- /// SizeExpr - An assignment expression that will instantiate to the
+ /// \brief An assignment expression that will instantiate to the
/// size of the array.
+ ///
+ /// The expression itself might be NULL, in which case the array
+ /// type will have its size deduced from an initializer.
Stmt *SizeExpr;
+
/// Brackets - The left and right array brackets.
SourceRange Brackets;
@@ -2272,6 +2281,8 @@ public:
static bool anyDependentTemplateArguments(const TemplateArgumentLoc *Args,
unsigned NumArgs);
+ static bool anyDependentTemplateArguments(const TemplateArgumentListInfo &);
+
/// \brief Print a template argument list, including the '<' and '>'
/// enclosing the template arguments.
static std::string PrintTemplateArgumentList(const TemplateArgument *Args,
@@ -2282,6 +2293,9 @@ public:
unsigned NumArgs,
const PrintingPolicy &Policy);
+ static std::string PrintTemplateArgumentList(const TemplateArgumentListInfo &,
+ const PrintingPolicy &Policy);
+
typedef const TemplateArgument * iterator;
iterator begin() const { return getArgs(); }
@@ -2534,6 +2548,7 @@ public:
return getPointeeType()->isSpecificBuiltinType(BuiltinType::ObjCClass) &&
!Protocols.size();
}
+
/// isObjCQualifiedIdType - true for "id <p>".
bool isObjCQualifiedIdType() const {
return getPointeeType()->isSpecificBuiltinType(BuiltinType::ObjCId) &&
@@ -2881,8 +2896,13 @@ inline bool Type::isObjCClassType() const {
return OPT->isObjCClassType();
return false;
}
+inline bool Type::isObjCSelType() const {
+ if (const PointerType *OPT = getAs<PointerType>())
+ return OPT->getPointeeType()->isSpecificBuiltinType(BuiltinType::ObjCSel);
+ return false;
+}
inline bool Type::isObjCBuiltinType() const {
- return isObjCIdType() || isObjCClassType();
+ return isObjCIdType() || isObjCClassType() || isObjCSelType();
}
inline bool Type::isTemplateTypeParmType() const {
return isa<TemplateTypeParmType>(CanonicalType);
diff --git a/include/clang/Analysis/Analyses/LiveVariables.h b/include/clang/Analysis/Analyses/LiveVariables.h
index 8674943..0077a85 100644
--- a/include/clang/Analysis/Analyses/LiveVariables.h
+++ b/include/clang/Analysis/Analyses/LiveVariables.h
@@ -23,6 +23,7 @@ namespace clang {
class Stmt;
class DeclRefExpr;
class SourceManager;
+class AnalysisContext;
struct LiveVariables_ValueTypes {
@@ -39,8 +40,9 @@ struct LiveVariables_ValueTypes {
struct AnalysisDataTy : public StmtDeclBitVector_Types::AnalysisDataTy {
ObserverTy* Observer;
ValTy AlwaysLive;
+ AnalysisContext *AC;
- AnalysisDataTy() : Observer(NULL) {}
+ AnalysisDataTy() : Observer(NULL), AC(NULL) {}
};
//===-----------------------------------------------------===//
@@ -66,7 +68,7 @@ class LiveVariables : public DataflowValues<LiveVariables_ValueTypes,
public:
typedef LiveVariables_ValueTypes::ObserverTy ObserverTy;
- LiveVariables(ASTContext& Ctx, CFG& cfg);
+ LiveVariables(AnalysisContext &AC);
/// IsLive - Return true if a variable is live at beginning of a
/// specified block.
diff --git a/include/clang/Analysis/PathDiagnostic.h b/include/clang/Analysis/PathDiagnostic.h
index efc6677..cad702c 100644
--- a/include/clang/Analysis/PathDiagnostic.h
+++ b/include/clang/Analysis/PathDiagnostic.h
@@ -14,31 +14,24 @@
#ifndef LLVM_CLANG_PATH_DIAGNOSTIC_H
#define LLVM_CLANG_PATH_DIAGNOSTIC_H
-#include "clang/Basic/SourceManager.h"
#include "clang/Basic/Diagnostic.h"
-#include "llvm/ADT/OwningPtr.h"
#include "llvm/ADT/FoldingSet.h"
-
-#include <vector>
#include <deque>
+#include <iterator>
#include <string>
-#include <algorithm>
+#include <vector>
namespace clang {
-
-class Stmt;
+
class Decl;
-class Preprocessor;
-
+class SourceManager;
+class Stmt;
+
//===----------------------------------------------------------------------===//
// High-level interface for handlers of path-sensitive diagnostics.
//===----------------------------------------------------------------------===//
class PathDiagnostic;
-
-class Stmt;
-class Decl;
-class Preprocessor;
class PathDiagnosticClient : public DiagnosticClient {
public:
diff --git a/include/clang/Analysis/PathSensitive/AnalysisContext.h b/include/clang/Analysis/PathSensitive/AnalysisContext.h
index 9b58f74..8b1a329 100644
--- a/include/clang/Analysis/PathSensitive/AnalysisContext.h
+++ b/include/clang/Analysis/PathSensitive/AnalysisContext.h
@@ -19,6 +19,7 @@
#include "llvm/ADT/OwningPtr.h"
#include "llvm/ADT/FoldingSet.h"
#include "llvm/ADT/DenseMap.h"
+#include "llvm/Support/Allocator.h"
namespace clang {
@@ -38,17 +39,26 @@ class AnalysisContext {
CFG *cfg;
LiveVariables *liveness;
ParentMap *PM;
-
+ llvm::DenseMap<const BlockDecl*,void*> *ReferencedBlockVars;
+ llvm::BumpPtrAllocator A;
public:
- AnalysisContext(const Decl *d) : D(d), cfg(0), liveness(0), PM(0) {}
+ AnalysisContext(const Decl *d) : D(d), cfg(0), liveness(0), PM(0),
+ ReferencedBlockVars(0) {}
+
~AnalysisContext();
+ ASTContext &getASTContext() { return D->getASTContext(); }
const Decl *getDecl() { return D; }
Stmt *getBody();
CFG *getCFG();
ParentMap &getParentMap();
LiveVariables *getLiveVariables();
+ typedef const VarDecl * const * referenced_decls_iterator;
+
+ std::pair<referenced_decls_iterator, referenced_decls_iterator>
+ getReferencedBlockVars(const BlockDecl *BD);
+
/// Return the ImplicitParamDecl* associated with 'self' if this
/// AnalysisContext wraps an ObjCMethodDecl. Returns NULL otherwise.
const ImplicitParamDecl *getSelfDecl() const;
diff --git a/include/clang/Analysis/PathSensitive/BugReporter.h b/include/clang/Analysis/PathSensitive/BugReporter.h
index f429735..58c8018 100644
--- a/include/clang/Analysis/PathSensitive/BugReporter.h
+++ b/include/clang/Analysis/PathSensitive/BugReporter.h
@@ -309,32 +309,33 @@ public:
void EmitReport(BugReport *R);
- void EmitBasicReport(const char* BugName, const char* BugStr,
+ void EmitBasicReport(llvm::StringRef BugName, llvm::StringRef BugStr,
SourceLocation Loc,
SourceRange* RangeBeg, unsigned NumRanges);
- void EmitBasicReport(const char* BugName, const char* BugCategory,
- const char* BugStr, SourceLocation Loc,
+ void EmitBasicReport(llvm::StringRef BugName, llvm::StringRef BugCategory,
+ llvm::StringRef BugStr, SourceLocation Loc,
SourceRange* RangeBeg, unsigned NumRanges);
- void EmitBasicReport(const char* BugName, const char* BugStr,
+ void EmitBasicReport(llvm::StringRef BugName, llvm::StringRef BugStr,
SourceLocation Loc) {
EmitBasicReport(BugName, BugStr, Loc, 0, 0);
}
- void EmitBasicReport(const char* BugName, const char* BugCategory,
- const char* BugStr, SourceLocation Loc) {
+ void EmitBasicReport(llvm::StringRef BugName, llvm::StringRef BugCategory,
+ llvm::StringRef BugStr, SourceLocation Loc) {
EmitBasicReport(BugName, BugCategory, BugStr, Loc, 0, 0);
}
- void EmitBasicReport(const char* BugName, const char* BugStr,
+ void EmitBasicReport(llvm::StringRef BugName, llvm::StringRef BugStr,
SourceLocation Loc, SourceRange R) {
EmitBasicReport(BugName, BugStr, Loc, &R, 1);
}
- void EmitBasicReport(const char* BugName, const char* Category,
- const char* BugStr, SourceLocation Loc, SourceRange R) {
+ void EmitBasicReport(llvm::StringRef BugName, llvm::StringRef Category,
+ llvm::StringRef BugStr, SourceLocation Loc,
+ SourceRange R) {
EmitBasicReport(BugName, Category, BugStr, Loc, &R, 1);
}
@@ -432,7 +433,7 @@ class DiagBugReport : public RangedBugReport {
std::list<std::string> Strs;
FullSourceLoc L;
public:
- DiagBugReport(BugType& D, const char* desc, FullSourceLoc l) :
+ DiagBugReport(BugType& D, llvm::StringRef desc, FullSourceLoc l) :
RangedBugReport(D, desc, 0), L(l) {}
virtual ~DiagBugReport() {}
diff --git a/include/clang/Analysis/PathSensitive/BugType.h b/include/clang/Analysis/PathSensitive/BugType.h
index 8303dee..4f1523a 100644
--- a/include/clang/Analysis/PathSensitive/BugType.h
+++ b/include/clang/Analysis/PathSensitive/BugType.h
@@ -34,13 +34,13 @@ private:
friend class BugReporter;
bool SuppressonSink;
public:
- BugType(const char *name, const char* cat)
+ BugType(llvm::StringRef name, llvm::StringRef cat)
: Name(name), Category(cat), SuppressonSink(false) {}
virtual ~BugType();
// FIXME: Should these be made strings as well?
- const std::string& getName() const { return Name; }
- const std::string& getCategory() const { return Category; }
+ llvm::StringRef getName() const { return Name; }
+ llvm::StringRef getCategory() const { return Category; }
/// isSuppressOnSink - Returns true if bug reports associated with this bug
/// type should be suppressed if the end node of the report is post-dominated
@@ -60,33 +60,15 @@ public:
};
class BuiltinBug : public BugType {
- GRExprEngine *Eng;
-protected:
const std::string desc;
public:
BuiltinBug(const char *name, const char *description)
- : BugType(name, "Logic error"), Eng(0), desc(description) {}
+ : BugType(name, "Logic error"), desc(description) {}
BuiltinBug(const char *name)
- : BugType(name, "Logic error"), Eng(0), desc(name) {}
+ : BugType(name, "Logic error"), desc(name) {}
- BuiltinBug(GRExprEngine *eng, const char* n, const char* d)
- : BugType(n, "Logic error"), Eng(eng), desc(d) {}
-
- BuiltinBug(GRExprEngine *eng, const char* n)
- : BugType(n, "Logic error"), Eng(eng), desc(n) {}
-
- const std::string &getDescription() const { return desc; }
-
- virtual void FlushReportsImpl(BugReporter& BR, GRExprEngine& Eng) {}
-
- void FlushReports(BugReporter& BR) { FlushReportsImpl(BR, *Eng); }
-
- virtual void registerInitialVisitors(BugReporterContext& BRC,
- const ExplodedNode* N,
- BuiltinBugReport *R) {}
-
- template <typename ITER> void Emit(BugReporter& BR, ITER I, ITER E);
+ llvm::StringRef getDescription() const { return desc; }
};
} // end clang namespace
diff --git a/include/clang/Analysis/PathSensitive/Checker.h b/include/clang/Analysis/PathSensitive/Checker.h
index b7ed20f..91a4b6d 100644
--- a/include/clang/Analysis/PathSensitive/Checker.h
+++ b/include/clang/Analysis/PathSensitive/Checker.h
@@ -40,24 +40,35 @@ class CheckerContext {
SaveAndRestore<ProgramPoint::Kind> OldPointKind;
SaveOr OldHasGen;
const GRState *state;
-
+ const Stmt *statement;
+ const unsigned size;
+ bool DoneEvaluating; // FIXME: This is not a permanent API change.
public:
CheckerContext(ExplodedNodeSet &dst, GRStmtNodeBuilder &builder,
GRExprEngine &eng, ExplodedNode *pred,
const void *tag, ProgramPoint::Kind K,
- const GRState *st = 0)
+ const Stmt *stmt = 0, const GRState *st = 0)
: Dst(dst), B(builder), Eng(eng), Pred(pred),
OldSink(B.BuildSinks),
OldTag(B.Tag, tag),
OldPointKind(B.PointKind, K),
OldHasGen(B.HasGeneratedNode),
- state(st) {}
+ state(st), statement(stmt), size(Dst.size()),
+ DoneEvaluating(false) {}
- ~CheckerContext() {
- if (!B.BuildSinks && !B.HasGeneratedNode)
- Dst.Add(Pred);
+ ~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;
+ }
+
ConstraintManager &getConstraintManager() {
return Eng.getConstraintManager();
}
@@ -83,27 +94,70 @@ public:
return getBugReporter().getSourceManager();
}
- ExplodedNode *GenerateNode(const Stmt *S, bool markAsSink = false) {
- return GenerateNode(S, getState(), markAsSink);
+ ValueManager &getValueManager() {
+ return Eng.getValueManager();
}
- ExplodedNode *GenerateNode(const Stmt* S, const GRState *state,
- bool markAsSink = false) {
- ExplodedNode *node = B.generateNode(S, state, Pred);
+ ExplodedNode *GenerateNode(bool autoTransition = true) {
+ assert(statement && "Only transitions with statements currently supported");
+ ExplodedNode *N = GenerateNodeImpl(statement, getState(), false);
+ if (N && autoTransition)
+ Dst.Add(N);
+ return N;
+ }
+
+ ExplodedNode *GenerateNode(const Stmt *stmt, const GRState *state,
+ bool autoTransition = true) {
+ assert(state);
+ ExplodedNode *N = GenerateNodeImpl(stmt, state, false);
+ if (N && autoTransition)
+ addTransition(N);
+ return N;
+ }
- if (markAsSink && node)
- node->markAsSink();
+ ExplodedNode *GenerateNode(const GRState *state, bool autoTransition = true) {
+ assert(statement && "Only transitions with statements currently supported");
+ ExplodedNode *N = GenerateNodeImpl(statement, state, false);
+ if (N && autoTransition)
+ addTransition(N);
+ return N;
+ }
- return node;
+ ExplodedNode *GenerateSink(const Stmt *stmt, const GRState *state = 0) {
+ return GenerateNodeImpl(stmt, state ? state : getState(), true);
+ }
+
+ ExplodedNode *GenerateSink(const GRState *state = 0) {
+ assert(statement && "Only transitions with statements currently supported");
+ return GenerateNodeImpl(statement, state ? state : getState(), true);
}
void addTransition(ExplodedNode *node) {
Dst.Add(node);
}
+
+ void addTransition(const GRState *state) {
+ assert(state);
+ if (state != getState() ||
+ (state && state != B.GetState(Pred)))
+ GenerateNode(state, true);
+ else
+ Dst.Add(Pred);
+ }
void EmitReport(BugReport *R) {
Eng.getBugReporter().EmitReport(R);
}
+
+private:
+ ExplodedNode *GenerateNodeImpl(const Stmt* stmt, const GRState *state,
+ bool markAsSink) {
+ ExplodedNode *node = B.generateNode(stmt, state, Pred);
+ if (markAsSink && node)
+ node->markAsSink();
+ return node;
+ }
+
};
class Checker {
@@ -111,18 +165,19 @@ private:
friend class GRExprEngine;
// FIXME: Remove the 'tag' option.
- void GR_Visit(ExplodedNodeSet &Dst,
+ bool GR_Visit(ExplodedNodeSet &Dst,
GRStmtNodeBuilder &Builder,
GRExprEngine &Eng,
const Stmt *S,
ExplodedNode *Pred, void *tag, bool isPrevisit) {
CheckerContext C(Dst, Builder, Eng, Pred, tag,
isPrevisit ? ProgramPoint::PreStmtKind :
- ProgramPoint::PostStmtKind);
+ ProgramPoint::PostStmtKind, S);
if (isPrevisit)
_PreVisit(C, S);
else
_PostVisit(C, S);
+ return C.isDoneEvaluating();
}
// FIXME: Remove the 'tag' option.
@@ -134,7 +189,7 @@ private:
bool isPrevisit) {
CheckerContext C(Dst, Builder, Eng, Pred, tag,
isPrevisit ? ProgramPoint::PreStmtKind :
- ProgramPoint::PostStmtKind);
+ ProgramPoint::PostStmtKind, StoreE);
assert(isPrevisit && "Only previsit supported for now.");
PreVisitBind(C, AssignE, StoreE, location, val);
}
@@ -149,7 +204,7 @@ private:
void *tag, bool isLoad) {
CheckerContext C(Dst, Builder, Eng, Pred, tag,
isLoad ? ProgramPoint::PreLoadKind :
- ProgramPoint::PreStoreKind, state);
+ ProgramPoint::PreStoreKind, S, state);
VisitLocation(C, S, location);
}
@@ -157,12 +212,12 @@ private:
GRExprEngine &Eng, const Stmt *S, ExplodedNode *Pred,
SymbolReaper &SymReaper, void *tag) {
CheckerContext C(Dst, Builder, Eng, Pred, tag,
- ProgramPoint::PostPurgeDeadSymbolsKind, Pred->getState());
+ ProgramPoint::PostPurgeDeadSymbolsKind, S);
EvalDeadSymbols(C, S, SymReaper);
}
public:
- virtual ~Checker() {}
+ virtual ~Checker();
virtual void _PreVisit(CheckerContext &C, const Stmt *S) {}
virtual void _PostVisit(CheckerContext &C, const Stmt *S) {}
virtual void VisitLocation(CheckerContext &C, const Stmt *S, SVal location) {}
@@ -172,6 +227,10 @@ public:
SymbolReaper &SymReaper) {}
virtual void EvalEndPath(GREndPathNodeBuilder &B, void *tag,
GRExprEngine &Eng) {}
+
+ virtual void VisitBranchCondition(GRBranchNodeBuilder &Builder,
+ GRExprEngine &Eng,
+ Stmt *Condition, void *tag) {}
};
} // end clang namespace
diff --git a/include/clang/Analysis/PathSensitive/CheckerVisitor.def b/include/clang/Analysis/PathSensitive/CheckerVisitor.def
index 090a5d3..4144d1a 100644
--- a/include/clang/Analysis/PathSensitive/CheckerVisitor.def
+++ b/include/clang/Analysis/PathSensitive/CheckerVisitor.def
@@ -11,7 +11,14 @@
//
//===---------------------------------------------------------------------===//
-#ifdef PREVISIT
+#ifndef PREVISIT
+#define PREVISIT(NODE)
+#endif
+
+#ifndef POSTVISIT
+#define POSTVISIT(NODE)
+#endif
+
PREVISIT(ArraySubscriptExpr)
PREVISIT(BinaryOperator)
PREVISIT(CallExpr)
@@ -19,11 +26,10 @@ PREVISIT(CastExpr)
PREVISIT(DeclStmt)
PREVISIT(ObjCMessageExpr)
PREVISIT(ReturnStmt)
-#undef PREVISIT
-#endif
-#ifdef POSTVISIT
POSTVISIT(CallExpr)
-#undef POSTVISIT
-#endif
+POSTVISIT(BlockExpr)
+POSTVISIT(BinaryOperator)
+#undef PREVISIT
+#undef POSTVISIT
diff --git a/include/clang/Analysis/PathSensitive/Checkers/UndefinedAssignmentChecker.h b/include/clang/Analysis/PathSensitive/Checkers/UndefinedAssignmentChecker.h
deleted file mode 100644
index 13437eb..0000000
--- a/include/clang/Analysis/PathSensitive/Checkers/UndefinedAssignmentChecker.h
+++ /dev/null
@@ -1,33 +0,0 @@
-//===--- UndefinedAssignmentChecker.h ---------------------------*- C++ -*--==//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This defines UndefinedAssginmentChecker, a builtin check in GRExprEngine that
-// checks for assigning undefined values.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_UNDEFASSIGNMENTCHECKER
-#define LLVM_CLANG_UNDEFASSIGNMENTCHECKER
-
-#include "clang/Analysis/PathSensitive/CheckerVisitor.h"
-
-namespace clang {
-class UndefinedAssignmentChecker
- : public CheckerVisitor<UndefinedAssignmentChecker> {
- BugType *BT;
-public:
- UndefinedAssignmentChecker() : BT(0) {}
- static void *getTag();
- virtual void PreVisitBind(CheckerContext &C, const Stmt *AssignE,
- const Stmt *StoreE, SVal location,
- SVal val);
-};
-}
-#endif
-
diff --git a/include/clang/Analysis/PathSensitive/ExplodedGraph.h b/include/clang/Analysis/PathSensitive/ExplodedGraph.h
index a7bbdf9..76cab1d 100644
--- a/include/clang/Analysis/PathSensitive/ExplodedGraph.h
+++ b/include/clang/Analysis/PathSensitive/ExplodedGraph.h
@@ -352,10 +352,16 @@ public:
typedef ImplTy::iterator iterator;
typedef ImplTy::const_iterator const_iterator;
- inline unsigned size() const { return Impl.size(); }
- inline bool empty() const { return Impl.empty(); }
-
- inline void clear() { Impl.clear(); }
+ unsigned size() const { return Impl.size(); }
+ bool empty() const { return Impl.empty(); }
+
+ void clear() { Impl.clear(); }
+ void insert(const ExplodedNodeSet &S) {
+ if (empty())
+ Impl = S.Impl;
+ else
+ Impl.insert(S.begin(), S.end());
+ }
inline iterator begin() { return Impl.begin(); }
inline iterator end() { return Impl.end(); }
diff --git a/include/clang/Analysis/PathSensitive/GRCoreEngine.h b/include/clang/Analysis/PathSensitive/GRCoreEngine.h
index 02e0b027..b78cc6a 100644
--- a/include/clang/Analysis/PathSensitive/GRCoreEngine.h
+++ b/include/clang/Analysis/PathSensitive/GRCoreEngine.h
@@ -215,7 +215,7 @@ public:
void setAuditor(GRAuditor* A) { Auditor = A; }
const GRState* GetState(ExplodedNode* Pred) const {
- if ((ExplodedNode*) Pred == getBasePredecessor())
+ if (Pred == getBasePredecessor())
return CleanedState;
else
return Pred->getState();
@@ -405,6 +405,8 @@ class GREndPathNodeBuilder {
GRCoreEngine& Eng;
CFGBlock& B;
ExplodedNode* Pred;
+
+public:
bool HasGeneratedNode;
public:
diff --git a/include/clang/Analysis/PathSensitive/GRExprEngine.h b/include/clang/Analysis/PathSensitive/GRExprEngine.h
index 1b6d0bd..a7302c0 100644
--- a/include/clang/Analysis/PathSensitive/GRExprEngine.h
+++ b/include/clang/Analysis/PathSensitive/GRExprEngine.h
@@ -88,55 +88,6 @@ class GRExprEngine : public GRSubEngine {
GRBugReporter BR;
public:
- typedef llvm::SmallPtrSet<ExplodedNode*,2> ErrorNodes;
- typedef llvm::DenseMap<ExplodedNode*, Expr*> UndefArgsTy;
-
- /// NilReceiverStructRetExplicit - Nodes in the ExplodedGraph that resulted
- /// from [x ...] with 'x' definitely being nil and the result was a 'struct'
- // (an undefined value).
- ErrorNodes NilReceiverStructRetExplicit;
-
- /// NilReceiverStructRetImplicit - Nodes in the ExplodedGraph that resulted
- /// from [x ...] with 'x' possibly being nil and the result was a 'struct'
- // (an undefined value).
- ErrorNodes NilReceiverStructRetImplicit;
-
- /// NilReceiverLargerThanVoidPtrRetExplicit - Nodes in the ExplodedGraph that
- /// resulted from [x ...] with 'x' definitely being nil and the result's size
- // was larger than sizeof(void *) (an undefined value).
- ErrorNodes NilReceiverLargerThanVoidPtrRetExplicit;
-
- /// NilReceiverLargerThanVoidPtrRetImplicit - Nodes in the ExplodedGraph that
- /// resulted from [x ...] with 'x' possibly being nil and the result's size
- // was larger than sizeof(void *) (an undefined value).
- ErrorNodes NilReceiverLargerThanVoidPtrRetImplicit;
-
- /// UndefBranches - Nodes in the ExplodedGraph that result from
- /// taking a branch based on an undefined value.
- ErrorNodes UndefBranches;
-
- /// UndefStores - Sinks in the ExplodedGraph that result from
- /// making a store to an undefined lvalue.
- ErrorNodes UndefStores;
-
- /// NoReturnCalls - Sinks in the ExplodedGraph that result from
- // calling a function with the attribute "noreturn".
- ErrorNodes NoReturnCalls;
-
- /// UndefResults - Nodes in the ExplodedGraph where the operands are defined
- /// by the result is not. Excludes divide-by-zero errors.
- ErrorNodes UndefResults;
-
- /// UndefReceiver - Nodes in the ExplodedGraph resulting from message
- /// ObjC message expressions where the receiver is undefined (uninitialized).
- ErrorNodes UndefReceivers;
-
- /// MsgExprUndefArgs - Nodes in the ExplodedGraph resulting from
- /// message expressions where a pass-by-value argument has an undefined
- /// value.
- UndefArgsTy MsgExprUndefArgs;
-
-public:
GRExprEngine(AnalysisManager &mgr);
~GRExprEngine();
@@ -178,8 +129,6 @@ public:
ExplodedGraph& getGraph() { return G; }
const ExplodedGraph& getGraph() const { return G; }
- void RegisterInternalChecks();
-
template <typename CHECKER>
void registerCheck(CHECKER *check) {
unsigned entry = Checkers.size();
@@ -195,58 +144,6 @@ public:
return static_cast<CHECKER*>(lookupChecker(CHECKER::getTag()));
}
- bool isNoReturnCall(const ExplodedNode* N) const {
- return N->isSink() && NoReturnCalls.count(const_cast<ExplodedNode*>(N)) != 0;
- }
-
- typedef ErrorNodes::iterator undef_branch_iterator;
- undef_branch_iterator undef_branches_begin() { return UndefBranches.begin(); }
- undef_branch_iterator undef_branches_end() { return UndefBranches.end(); }
-
- typedef ErrorNodes::iterator nil_receiver_struct_ret_iterator;
-
- nil_receiver_struct_ret_iterator nil_receiver_struct_ret_begin() {
- return NilReceiverStructRetExplicit.begin();
- }
-
- nil_receiver_struct_ret_iterator nil_receiver_struct_ret_end() {
- return NilReceiverStructRetExplicit.end();
- }
-
- typedef ErrorNodes::iterator nil_receiver_larger_than_voidptr_ret_iterator;
-
- nil_receiver_larger_than_voidptr_ret_iterator
- nil_receiver_larger_than_voidptr_ret_begin() {
- return NilReceiverLargerThanVoidPtrRetExplicit.begin();
- }
-
- nil_receiver_larger_than_voidptr_ret_iterator
- nil_receiver_larger_than_voidptr_ret_end() {
- return NilReceiverLargerThanVoidPtrRetExplicit.end();
- }
-
- typedef ErrorNodes::iterator undef_result_iterator;
- undef_result_iterator undef_results_begin() { return UndefResults.begin(); }
- undef_result_iterator undef_results_end() { return UndefResults.end(); }
-
- typedef UndefArgsTy::iterator undef_arg_iterator;
- undef_arg_iterator msg_expr_undef_arg_begin() {
- return MsgExprUndefArgs.begin();
- }
- undef_arg_iterator msg_expr_undef_arg_end() {
- return MsgExprUndefArgs.end();
- }
-
- typedef ErrorNodes::iterator undef_receivers_iterator;
-
- undef_receivers_iterator undef_receivers_begin() {
- return UndefReceivers.begin();
- }
-
- undef_receivers_iterator undef_receivers_end() {
- return UndefReceivers.end();
- }
-
void AddCheck(GRSimpleAPICheck* A, Stmt::StmtClass C);
void AddCheck(GRSimpleAPICheck* A);
@@ -312,7 +209,7 @@ public:
protected:
/// CheckerVisit - Dispatcher for performing checker-specific logic
/// at specific statements.
- void CheckerVisit(Stmt *S, ExplodedNodeSet &Dst, ExplodedNodeSet &Src,
+ bool CheckerVisit(Stmt *S, ExplodedNodeSet &Dst, ExplodedNodeSet &Src,
bool isPrevisit);
void CheckerVisitBind(const Stmt *AssignE, const Stmt *StoreE,
@@ -345,6 +242,9 @@ protected:
AsmStmt::inputs_iterator I,
AsmStmt::inputs_iterator E,
ExplodedNode* Pred, ExplodedNodeSet& Dst);
+
+ /// VisitBlockExpr - Transfer function logic for BlockExprs.
+ void VisitBlockExpr(BlockExpr *BE, ExplodedNode *Pred, ExplodedNodeSet &Dst);
/// VisitBinaryOperator - Transfer function logic for binary operators.
void VisitBinaryOperator(BinaryOperator* B, ExplodedNode* Pred,
@@ -361,33 +261,38 @@ protected:
unsigned ParamIdx = 0);
/// VisitCast - Transfer function logic for all casts (implicit and explicit).
- void VisitCast(Expr* CastE, Expr* Ex, ExplodedNode* Pred, ExplodedNodeSet& Dst);
+ void VisitCast(Expr* CastE, Expr* Ex, ExplodedNode* Pred,
+ ExplodedNodeSet& Dst);
/// VisitCompoundLiteralExpr - Transfer function logic for compound literals.
void VisitCompoundLiteralExpr(CompoundLiteralExpr* CL, ExplodedNode* Pred,
ExplodedNodeSet& Dst, bool asLValue);
/// VisitDeclRefExpr - Transfer function logic for DeclRefExprs.
- void VisitDeclRefExpr(DeclRefExpr* DR, ExplodedNode* Pred, ExplodedNodeSet& Dst,
- bool asLValue);
+ void VisitDeclRefExpr(DeclRefExpr* DR, ExplodedNode* Pred,
+ ExplodedNodeSet& Dst, bool asLValue);
/// VisitDeclStmt - Transfer function logic for DeclStmts.
void VisitDeclStmt(DeclStmt* DS, ExplodedNode* Pred, ExplodedNodeSet& Dst);
/// VisitGuardedExpr - Transfer function logic for ?, __builtin_choose
- void VisitGuardedExpr(Expr* Ex, Expr* L, Expr* R, ExplodedNode* Pred, ExplodedNodeSet& Dst);
+ void VisitGuardedExpr(Expr* Ex, Expr* L, Expr* R, ExplodedNode* Pred,
+ ExplodedNodeSet& Dst);
- void VisitInitListExpr(InitListExpr* E, ExplodedNode* Pred, ExplodedNodeSet& Dst);
+ void VisitInitListExpr(InitListExpr* E, ExplodedNode* Pred,
+ ExplodedNodeSet& Dst);
/// VisitLogicalExpr - Transfer function logic for '&&', '||'
- void VisitLogicalExpr(BinaryOperator* B, ExplodedNode* Pred, ExplodedNodeSet& Dst);
+ void VisitLogicalExpr(BinaryOperator* B, ExplodedNode* Pred,
+ ExplodedNodeSet& Dst);
/// VisitMemberExpr - Transfer function for member expressions.
- void VisitMemberExpr(MemberExpr* M, ExplodedNode* Pred, ExplodedNodeSet& Dst,bool asLValue);
+ void VisitMemberExpr(MemberExpr* M, ExplodedNode* Pred, ExplodedNodeSet& Dst,
+ bool asLValue);
/// VisitObjCIvarRefExpr - Transfer function logic for ObjCIvarRefExprs.
- void VisitObjCIvarRefExpr(ObjCIvarRefExpr* DR, ExplodedNode* Pred, ExplodedNodeSet& Dst,
- bool asLValue);
+ void VisitObjCIvarRefExpr(ObjCIvarRefExpr* DR, ExplodedNode* Pred,
+ ExplodedNodeSet& Dst, bool asLValue);
/// VisitObjCForCollectionStmt - Transfer function logic for
/// ObjCForCollectionStmt.
diff --git a/include/clang/Analysis/PathSensitive/GRState.h b/include/clang/Analysis/PathSensitive/GRState.h
index ef0c36c..d8bc241 100644
--- a/include/clang/Analysis/PathSensitive/GRState.h
+++ b/include/clang/Analysis/PathSensitive/GRState.h
@@ -33,7 +33,6 @@
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/DenseSet.h"
#include "llvm/Support/Allocator.h"
-#include "llvm/Support/Compiler.h"
#include "llvm/Support/raw_ostream.h"
#include <functional>
@@ -264,8 +263,21 @@ public:
const llvm::APSInt *getSymVal(SymbolRef sym);
bool scanReachableSymbols(SVal val, SymbolVisitor& visitor) const;
+
+ bool scanReachableSymbols(const SVal *I, const SVal *E,
+ SymbolVisitor &visitor) const;
+
+ bool scanReachableSymbols(const MemRegion * const *I,
+ const MemRegion * const *E,
+ SymbolVisitor &visitor) const;
template <typename CB> CB scanReachableSymbols(SVal val) const;
+ template <typename CB> CB scanReachableSymbols(const SVal *beg,
+ const SVal *end) const;
+
+ template <typename CB> CB
+ scanReachableSymbols(const MemRegion * const *beg,
+ const MemRegion * const *end) const;
//==---------------------------------------------------------------------==//
// Accessing the Generic Data Map (GDM).
@@ -726,7 +738,21 @@ CB GRState::scanReachableSymbols(SVal val) const {
scanReachableSymbols(val, cb);
return cb;
}
+
+template <typename CB>
+CB GRState::scanReachableSymbols(const SVal *beg, const SVal *end) const {
+ CB cb(this);
+ scanReachableSymbols(beg, end, cb);
+ return cb;
+}
+template <typename CB>
+CB GRState::scanReachableSymbols(const MemRegion * const *beg,
+ const MemRegion * const *end) const {
+ CB cb(this);
+ scanReachableSymbols(beg, end, cb);
+ return cb;
+}
} // end clang namespace
#endif
diff --git a/include/clang/Analysis/PathSensitive/MemRegion.h b/include/clang/Analysis/PathSensitive/MemRegion.h
index 06d0d97..ed96497 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 VarRegion;
//===----------------------------------------------------------------------===//
// Base region classes.
@@ -42,13 +43,16 @@ class LocationContext;
/// MemRegion - The root abstract class for all memory regions.
class MemRegion : public llvm::FoldingSetNode {
+ friend class MemRegionManager;
public:
enum Kind { MemSpaceRegionKind,
SymbolicRegionKind,
AllocaRegionKind,
// Typed regions.
BEG_TYPED_REGIONS,
- CodeTextRegionKind,
+ FunctionTextRegionKind,
+ BlockTextRegionKind,
+ BlockDataRegionKind,
CompoundLiteralRegionKind,
StringRegionKind, ElementRegionKind,
// Decl Regions.
@@ -237,45 +241,123 @@ public:
}
};
-/// CodeTextRegion - A region that represents code texts of a function. It wraps
-/// two kinds of code texts: real function and symbolic function. Real function
-/// is a function declared in the program. Symbolic function is a function
-/// pointer that we don't know which function it points to.
-class CodeTextRegion : public TypedRegion {
- const FunctionDecl *FD;
+class CodeTextRegion : public TypedRegion {
+protected:
+ CodeTextRegion(const MemRegion *sreg, Kind k) : TypedRegion(sreg, k) {}
public:
-
- CodeTextRegion(const FunctionDecl* fd, const MemRegion* sreg)
- : TypedRegion(sreg, CodeTextRegionKind), FD(fd) {}
-
QualType getValueType(ASTContext &C) const {
// Do not get the object type of a CodeTextRegion.
assert(0);
return QualType();
}
+
+ bool isBoundable() const { return false; }
+
+ static bool classof(const MemRegion* R) {
+ Kind k = R->getKind();
+ return k >= FunctionTextRegionKind && k <= BlockTextRegionKind;
+ }
+};
+/// FunctionTextRegion - A region that represents code texts of function.
+class FunctionTextRegion : public CodeTextRegion {
+ const FunctionDecl *FD;
+public:
+ FunctionTextRegion(const FunctionDecl* fd, const MemRegion* sreg)
+ : CodeTextRegion(sreg, FunctionTextRegionKind), FD(fd) {}
+
QualType getLocationType(ASTContext &C) const {
return C.getPointerType(FD->getType());
}
-
+
const FunctionDecl *getDecl() const {
return FD;
}
-
- bool isBoundable() const { return false; }
-
+
virtual void dumpToStream(llvm::raw_ostream& os) const;
-
+
void Profile(llvm::FoldingSetNodeID& ID) const;
-
+
static void ProfileRegion(llvm::FoldingSetNodeID& ID, const FunctionDecl *FD,
const MemRegion*);
-
+
+ static bool classof(const MemRegion* R) {
+ return R->getKind() == FunctionTextRegionKind;
+ }
+};
+
+
+/// BlockTextRegion - A region that represents code texts of blocks (closures).
+/// Blocks are represented with two kinds of regions. BlockTextRegions
+/// represent the "code", while BlockDataRegions represent instances of blocks,
+/// which correspond to "code+data". The distinction is important, because
+/// like a closure a block captures the values of externally referenced
+/// variables.
+class BlockTextRegion : public CodeTextRegion {
+ const BlockDecl *BD;
+ CanQualType locTy;
+public:
+ BlockTextRegion(const BlockDecl *bd, CanQualType lTy, const MemRegion* sreg)
+ : CodeTextRegion(sreg, BlockTextRegionKind), BD(bd), locTy(lTy) {}
+
+ QualType getLocationType(ASTContext &C) const {
+ return locTy;
+ }
+
+ const BlockDecl *getDecl() const {
+ return BD;
+ }
+
+ 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*);
+
static bool classof(const MemRegion* R) {
- return R->getKind() == CodeTextRegionKind;
+ return R->getKind() == BlockTextRegionKind;
}
};
+
+/// BlockDataRegion - A region that represents a block instance.
+/// Blocks are represented with two kinds of regions. BlockTextRegions
+/// represent the "code", while BlockDataRegions represent instances of blocks,
+/// which correspond to "code+data". The distinction is important, because
+/// like a closure a block captures the values of externally referenced
+/// variables.
+/// BlockDataRegion - A region that represents code texts of blocks (closures).
+class BlockDataRegion : public SubRegion {
+ const BlockTextRegion *BC;
+ const LocationContext *LC;
+ void *ReferencedVars;
+public:
+ BlockDataRegion(const BlockTextRegion *bc,
+ const LocationContext *lc,
+ const MemRegion *sreg)
+ : SubRegion(sreg, BlockDataRegionKind), BC(bc), LC(lc), ReferencedVars(0) {}
+
+ const BlockTextRegion *getCodeRegion() const { return BC; }
+
+ typedef const MemRegion * const * referenced_vars_iterator;
+ referenced_vars_iterator referenced_vars_begin() const;
+ referenced_vars_iterator referenced_vars_end() const;
+
+ virtual void dumpToStream(llvm::raw_ostream& os) const;
+
+ void Profile(llvm::FoldingSetNodeID& ID) const;
+
+ static void ProfileRegion(llvm::FoldingSetNodeID& ID,
+ const BlockTextRegion *BC,
+ const LocationContext *LC, const MemRegion *);
+
+ static bool classof(const MemRegion* R) {
+ return R->getKind() == BlockDataRegionKind;
+ }
+private:
+ void LazyInitializeReferencedVars();
+};
/// SymbolicRegion - A special, "non-concrete" region. Unlike other region
/// clases, SymbolicRegion represents a region that serves as an alias for
@@ -577,9 +659,11 @@ public:
: C(c), A(a), globals(0), stack(0), stackArguments(0), heap(0),
unknown(0), code(0) {}
- ~MemRegionManager() {}
+ ~MemRegionManager();
ASTContext &getContext() { return C; }
+
+ llvm::BumpPtrAllocator &getAllocator() { return A; }
/// getStackRegion - Retrieve the memory region associated with the
/// current stack frame.
@@ -656,7 +740,10 @@ public:
ObjCIvarRegion *getObjCIvarRegion(const ObjCIvarDecl* ivd,
const MemRegion* superRegion);
- CodeTextRegion *getCodeTextRegion(const FunctionDecl *FD);
+ FunctionTextRegion *getFunctionTextRegion(const FunctionDecl *FD);
+ BlockTextRegion *getBlockTextRegion(const BlockDecl *BD, CanQualType locTy);
+ BlockDataRegion *getBlockDataRegion(const BlockTextRegion *bc,
+ const LocationContext *lc);
template <typename RegionTy, typename A1>
RegionTy* getRegion(const A1 a1);
@@ -667,6 +754,10 @@ public:
template <typename RegionTy, typename A1, typename A2>
RegionTy* getRegion(const A1 a1, const A2 a2);
+ template <typename RegionTy, typename A1, typename A2>
+ RegionTy* getSubRegion(const A1 a1, const A2 a2,
+ const MemRegion* superRegion);
+
bool isGlobalsRegion(const MemRegion* R) {
assert(R);
return R == globals;
@@ -745,6 +836,25 @@ RegionTy* MemRegionManager::getRegion(const A1 a1, const A2 a2) {
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.
@@ -801,18 +911,21 @@ template <> struct MemRegionManagerTrait<SymbolicRegion> {
}
};
-template<> struct MemRegionManagerTrait<CodeTextRegion> {
+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,
- SymbolRef, QualType) {
+ const BlockDecl*, CanQualType) {
return MRMgr.getCodeRegion();
}
};
-
+
} // end clang namespace
//===----------------------------------------------------------------------===//
diff --git a/include/clang/Analysis/PathSensitive/ValueManager.h b/include/clang/Analysis/PathSensitive/ValueManager.h
index 8d162a6..ef4e069 100644
--- a/include/clang/Analysis/PathSensitive/ValueManager.h
+++ b/include/clang/Analysis/PathSensitive/ValueManager.h
@@ -114,6 +114,9 @@ public:
const TypedRegion *R);
DefinedSVal getFunctionPointer(const FunctionDecl *FD);
+
+ DefinedSVal getBlockPointer(const BlockDecl *BD, CanQualType locTy,
+ const LocationContext *LC);
NonLoc makeCompoundVal(QualType T, llvm::ImmutableList<SVal> Vals) {
return nonloc::CompoundVal(BasicVals.getCompoundValData(T, Vals));
diff --git a/include/clang/Basic/BuiltinsX86.def b/include/clang/Basic/BuiltinsX86.def
index 2af9580..bbf42ee 100644
--- a/include/clang/Basic/BuiltinsX86.def
+++ b/include/clang/Basic/BuiltinsX86.def
@@ -250,8 +250,8 @@ 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, "V2LLiV2LLiV2LLii", "")
-BUILTIN(__builtin_ia32_palignr, "V1LLiV1LLiV1LLis", "")
+BUILTIN(__builtin_ia32_palignr128, "V2LLiV2LLiV2LLic", "")
+BUILTIN(__builtin_ia32_palignr, "V1LLiV1LLiV1LLic", "")
BUILTIN(__builtin_ia32_insertps128, "V4fV4fV4fi", "")
BUILTIN(__builtin_ia32_storelv4si, "vV2i*V2LLi", "")
diff --git a/include/clang/Basic/DiagnosticDriverKinds.td b/include/clang/Basic/DiagnosticDriverKinds.td
index e2f1104..3f7d114 100644
--- a/include/clang/Basic/DiagnosticDriverKinds.td
+++ b/include/clang/Basic/DiagnosticDriverKinds.td
@@ -57,6 +57,9 @@ def err_drv_invalid_mfloat_abi : Error<
"invalid float ABI '%0'">;
def err_drv_I_dash_not_supported : Error<
"'%0' not supported, please use -iquote instead">;
+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 warn_drv_input_file_unused : Warning<
"%0: '%1' input unused when '%2' is present">;
diff --git a/include/clang/Basic/DiagnosticFrontendKinds.td b/include/clang/Basic/DiagnosticFrontendKinds.td
index e9b351f..cbc287c 100644
--- a/include/clang/Basic/DiagnosticFrontendKinds.td
+++ b/include/clang/Basic/DiagnosticFrontendKinds.td
@@ -17,6 +17,8 @@ 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_stdout_binary : Error<"unable to change standard output to binary">,
+ DefaultFatal;
def err_fe_dependency_file_requires_MT : Error<
"-dependency-file requires at least one -MT option">;
def err_fe_incompatible_options : Error<
diff --git a/include/clang/Basic/DiagnosticGroups.td b/include/clang/Basic/DiagnosticGroups.td
index 93c655b..c1c833c 100644
--- a/include/clang/Basic/DiagnosticGroups.td
+++ b/include/clang/Basic/DiagnosticGroups.td
@@ -78,16 +78,19 @@ def : DiagGroup<"synth">;
// Preprocessor warnings.
def : DiagGroup<"builtin-macro-redefined">;
-// Just silence warnings about common forms of -Wstrict-aliasing for now.
+// Just silence warnings about -Wstrict-aliasing for now.
def : DiagGroup<"strict-aliasing=0">;
def : DiagGroup<"strict-aliasing=1">;
def : DiagGroup<"strict-aliasing=2">;
def : DiagGroup<"strict-aliasing">;
-// Just silence warnings about common forms of -Wstrict-aliasing for now.
+// Just silence warnings about -Wstrict-overflow for now.
def : DiagGroup<"strict-overflow=0">;
def : DiagGroup<"strict-overflow=1">;
def : DiagGroup<"strict-overflow=2">;
+def : DiagGroup<"strict-overflow=3">;
+def : DiagGroup<"strict-overflow=4">;
+def : DiagGroup<"strict-overflow=5">;
def : DiagGroup<"strict-overflow">;
def InvalidOffsetof : DiagGroup<"invalid-offsetof">;
diff --git a/include/clang/Basic/DiagnosticLexKinds.td b/include/clang/Basic/DiagnosticLexKinds.td
index 7f3f4ea..39123d9 100644
--- a/include/clang/Basic/DiagnosticLexKinds.td
+++ b/include/clang/Basic/DiagnosticLexKinds.td
@@ -170,6 +170,8 @@ def ext_pp_counter : 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;
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 3a8c5bf..4310704 100644
--- a/include/clang/Basic/DiagnosticParseKinds.td
+++ b/include/clang/Basic/DiagnosticParseKinds.td
@@ -44,7 +44,8 @@ def ext_c99_variable_decl_in_for_loop : Extension<
def ext_c99_compound_literal : Extension<
"compound literals are a C99-specific feature">;
def ext_enumerator_list_comma : Extension<
- "commas at the end of enumerator lists are a %select{C99|C++0x}0-specific feature">;
+ "commas at the end of enumerator lists are a %select{C99|C++0x}0-specific "
+ "feature">;
def ext_gnu_indirect_goto : Extension<
"use of GNU indirect-goto extension">;
@@ -75,6 +76,7 @@ def err_expected_ident_lbrace : Error<"expected identifier or '{'">;
def err_expected_lbrace : Error<"expected '{'">;
def err_expected_lparen : Error<"expected '('">;
def err_expected_rparen : Error<"expected ')'">;
+def err_expected_lsquare : Error<"expected '['">;
def err_expected_rsquare : Error<"expected ']'">;
def err_expected_rbrace : Error<"expected '}'">;
def err_expected_greater : Error<"expected '>'">;
@@ -240,11 +242,18 @@ def err_dup_virtual : Error<"duplicate 'virtual' in base specifier">;
// C++ operator overloading
def err_operator_missing_type_specifier : Error<
"missing type specifier after 'operator'">;
+def err_operator_string_not_empty : Error<
+ "string literal after 'operator' must be '\"\"'">;
// Classes.
def err_anon_type_definition : Error<
"declaration of anonymous %0 must be a definition">;
+def err_cxx0x_attribute_forbids_arguments : Error<
+ "C++0x attribute '%0' cannot have an argument list">;
+def err_cxx0x_attribute_requires_arguments : Error<
+ "C++0x attribute '%0' must have an argument list">;
+def err_attributes_not_allowed : Error<"an attribute list cannot appear here">;
/// C++ Templates
def err_expected_template : Error<"expected template">;
diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td
index a864d8a..a0e03fe 100644
--- a/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/include/clang/Basic/DiagnosticSemaKinds.td
@@ -443,8 +443,9 @@ def err_implicit_object_parameter_init : Error<
def note_field_decl : Note<"member is declared here">;
def note_previous_class_decl : Note<
"%0 declared here">;
-def note_ctor_synthesized_at : Note<
- "implicit default constructor for %0 first required here">;
+def note_member_synthesized_at : Note<
+ "implicit default %select{constructor|copy constructor|"
+ "copy assignment operator|destructor}0 for %1 first required here">;
def err_missing_default_ctor : Error<
"%select{|implicit default }0constructor for %1 must explicitly initialize "
"the %select{base class|member}2 %3 which does not have a default "
@@ -552,6 +553,15 @@ def err_auto_not_allowed : Error<
def err_auto_var_requires_init : Error<
"declaration of variable %0 with type %1 requires an initializer">;
+// C++0x attributes
+def err_repeat_attribute : Error<"'%0' attribute cannot be repeated">;
+
+// C++0x [[final]]
+def err_final_function_overridden : Error<
+ "declaration of %0 overrides a 'final' function">;
+def err_final_base : Error<
+ "derivation from 'final' %0">;
+
// Objective-C++
def err_objc_decls_may_only_appear_in_global_scope : Error<
"Objective-C declarations may only appear in global scope">;
@@ -638,8 +648,16 @@ def warn_attribute_weak_import_invalid_on_definition : Warning<
"'weak_import' attribute cannot be specified on a definition">;
def warn_attribute_wrong_decl_type : Warning<
"%0 attribute only applies to %select{function|union|"
- "variable and function|function or method|parameter|parameter or Objective-C method |"
- "function, method or block}1 types">;
+ "variable and function|function or method|parameter|"
+ "parameter or Objective-C method |function, method or block|"
+ "virtual method or class|function, method, or parameter|class|virtual method"
+ "|member}1 types">;
+def err_attribute_wrong_decl_type : Error<
+ "%0 attribute only applies to %select{function|union|"
+ "variable and function|function or method|parameter|"
+ "parameter or Objective-C method |function, method or block|"
+ "virtual method or class|function, method, or parameter|class|virtual method"
+ "|member}1 types">;
def warn_gnu_inline_attribute_requires_inline : Warning<
"'gnu_inline' attribute requires function to be marked 'inline',"
" attribute ignored">;
@@ -865,7 +883,7 @@ def err_addr_ovl_ambiguous : Error<
def err_template_param_shadow : Error<
"declaration of %0 shadows template parameter">;
def note_template_param_here : Note<"template parameter is declared here">;
-def note_template_export_unsupported : Note<
+def warn_template_export_unsupported : Warning<
"exported templates are unsupported">;
def err_template_outside_namespace_or_class_scope : Error<
"templates can only be declared in namespace or class scope">;
@@ -902,7 +920,15 @@ def note_template_param_prev_default_arg : Note<
"previous default template argument defined here">;
def err_template_param_default_arg_missing : Error<
"template parameter missing a default argument">;
-
+def err_template_parameter_default_in_function_template : Error<
+ "a template parameter of a function template cannot have a default argument "
+ "in C++98">;
+def err_template_parameter_default_template_member : Error<
+ "cannot add a default template argument to the definition of a member of a "
+ "class template">;
+def err_template_parameter_default_friend_template : Error<
+ "default template argument not permitted on a friend template">;
+
def err_template_variable : Error<"variable %0 declared as a template">;
def err_template_variable_noparams : Error<
"extraneous 'template<>' in declaration of variable %0">;
@@ -1037,6 +1063,11 @@ def err_template_param_list_matches_nontemplate : Error<
def err_template_spec_extra_headers : Error<
"extraneous template parameter list in template specialization or "
"out-of-line template definition">;
+def warn_template_spec_extra_headers : Warning<
+ "extraneous template parameter list in template specialization">;
+def note_explicit_template_spec_does_not_need_header : Note<
+ "'template<>' header not required for explicitly-specialized class %0 "
+ "declared here">;
def err_template_qualified_declarator_no_match : Error<
"nested name specifier '%0' for declaration does not refer into a class, "
"class template or class template partial specialization">;
@@ -1197,6 +1228,10 @@ def err_template_kw_refers_to_non_template : Error<
"%0 following the 'template' keyword does not refer to a template">;
def err_template_kw_refers_to_function_template : Error<
"%0 following the 'template' keyword refers to a function template">;
+def err_template_kw_refers_to_class_template : Error<
+ "'%0%1' instantiated to a class template, not a function template">;
+def note_referenced_class_template : Error<
+ "class template declared here">;
// C++0x Variadic Templates
def err_template_param_pack_default_arg : Error<
@@ -2050,6 +2085,8 @@ def err_base_init_direct_and_virtual : Error<
"inherited virtual base class">;
def err_not_direct_base_or_virtual : Error<
"type %0 is not a direct or virtual base of '%1'">;
+def err_not_direct_base_or_virtual_multi : Error<
+ "type %0 is not a direct or virtual base of '%1'">;
def err_in_class_initializer_non_integral_type : Error<
"in-class initializer has non-integral, non-enumeration type %0">;
@@ -2275,6 +2312,15 @@ def err_typecheck_statement_requires_integer : Error<
"statement requires expression of integer type (%0 invalid)">;
def err_multiple_default_labels_defined : Error<
"multiple default labels in one switch">;
+def err_switch_multiple_conversions : Error<
+ "multiple conversions from switch condition type %0 to an integral or "
+ "enumeration type">;
+def note_switch_conversion : Note<
+ "conversion to %select{integral|enumeration}0 type %1">;
+def err_switch_explicit_conversion : Error<
+ "switch condition type %0 requires explicit conversion to %1">;
+def err_switch_incomplete_class_type : Error<
+ "switch condition has incomplete class type %0">;
def warn_empty_if_body : Warning<
"if statement has empty body">, InGroup<EmptyBody>;
def err_va_start_used_in_non_variadic_function : Error<
diff --git a/include/clang/Basic/IdentifierTable.h b/include/clang/Basic/IdentifierTable.h
index e06dfbb..5393950 100644
--- a/include/clang/Basic/IdentifierTable.h
+++ b/include/clang/Basic/IdentifierTable.h
@@ -496,6 +496,7 @@ public:
#define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly) \
CXXOperator##Name,
#include "clang/Basic/OperatorKinds.def"
+ CXXLiteralOperator,
CXXUsingDirective,
NUM_EXTRA_KINDS
};
@@ -503,10 +504,10 @@ public:
/// ExtraKindOrNumArgs - Either the kind of C++ special name or
/// operator-id (if the value is one of the CXX* enumerators of
/// ExtraKind), in which case the DeclarationNameExtra is also a
- /// CXXSpecialName (for CXXConstructor, CXXDestructor, or
- /// CXXConversionFunction) or CXXOperatorIdName, it may be also
- /// name common to C++ using-directives (CXXUsingDirective), otherwise
- /// it is NUM_EXTRA_KINDS+NumArgs, where NumArgs is the number of
+ /// CXXSpecialName, (for CXXConstructor, CXXDestructor, or
+ /// CXXConversionFunction) CXXOperatorIdName, or CXXLiteralOperatorName,
+ /// it may be also name common to C++ using-directives (CXXUsingDirective),
+ /// otherwise it is NUM_EXTRA_KINDS+NumArgs, where NumArgs is the number of
/// arguments in the Objective-C selector, in which case the
/// DeclarationNameExtra is also a MultiKeywordSelector.
unsigned ExtraKindOrNumArgs;
diff --git a/include/clang/Basic/LangOptions.h b/include/clang/Basic/LangOptions.h
index 99c100d..a16a271 100644
--- a/include/clang/Basic/LangOptions.h
+++ b/include/clang/Basic/LangOptions.h
@@ -14,6 +14,8 @@
#ifndef LLVM_CLANG_LANGOPTIONS_H
#define LLVM_CLANG_LANGOPTIONS_H
+#include <string>
+
namespace clang {
/// LangOptions - This class keeps track of the various options that can be
@@ -101,15 +103,10 @@ private:
// on making enums signed. Set/Query this
// value using accessors.
- /// The user provided name for the "main file", if non-null. This is
- /// useful in situations where the input file name does not match
- /// the original input file, for example with -save-temps.
- const char *MainFileName;
-
public:
unsigned InstantiationDepth; // Maximum template instantiation depth.
- const char *ObjCConstantStringClass;
+ std::string ObjCConstantStringClass;
enum GCMode { NonGC, GCOnly, HybridGC };
enum StackProtectorMode { SSPOff, SSPOn, SSPReq };
@@ -124,7 +121,6 @@ public:
GNUMode = ImplicitInt = Digraphs = 0;
HexFloats = 0;
GC = ObjC1 = ObjC2 = ObjCNonFragileABI = 0;
- ObjCConstantStringClass = 0;
C99 = Microsoft = CPlusPlus = CPlusPlus0x = 0;
CXXOperatorNames = PascalStrings = WritableStrings = 0;
Exceptions = Freestanding = NoBuiltin = 0;
@@ -164,8 +160,6 @@ public:
CharIsSigned = 1;
ShortWChar = 0;
-
- MainFileName = 0;
}
GCMode getGCMode() const { return (GCMode) GC; }
@@ -178,9 +172,6 @@ public:
StackProtector = static_cast<unsigned>(m);
}
- const char *getMainFileName() const { return MainFileName; }
- void setMainFileName(const char *Name) { MainFileName = Name; }
-
VisibilityMode getVisibilityMode() const {
return (VisibilityMode) SymbolVisibility;
}
diff --git a/include/clang/Basic/OnDiskHashTable.h b/include/clang/Basic/OnDiskHashTable.h
index 6b60f2e..9b50e8d 100644
--- a/include/clang/Basic/OnDiskHashTable.h
+++ b/include/clang/Basic/OnDiskHashTable.h
@@ -15,7 +15,6 @@
#define LLVM_CLANG_BASIC_ON_DISK_HASH_TABLE_H
#include "llvm/Support/Allocator.h"
-#include "llvm/Support/Compiler.h"
#include "llvm/System/DataTypes.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/raw_ostream.h"
diff --git a/include/clang/Basic/TargetInfo.h b/include/clang/Basic/TargetInfo.h
index 695f51d..49eaafe 100644
--- a/include/clang/Basic/TargetInfo.h
+++ b/include/clang/Basic/TargetInfo.h
@@ -80,7 +80,7 @@ public:
};
protected:
IntType SizeType, IntMaxType, UIntMaxType, PtrDiffType, IntPtrType, WCharType,
- WIntType, Char16Type, Char32Type, Int64Type;
+ WIntType, Char16Type, Char32Type, Int64Type, SigAtomicType;
public:
IntType getSizeType() const { return SizeType; }
IntType getIntMaxType() const { return IntMaxType; }
@@ -94,6 +94,7 @@ public:
IntType getChar16Type() const { return Char16Type; }
IntType getChar32Type() const { return Char32Type; }
IntType getInt64Type() const { return Int64Type; }
+ IntType getSigAtomicType() const { return SigAtomicType; }
/// getTypeWidth - Return the width (in bits) of the specified integer type
diff --git a/include/clang/Basic/TokenKinds.def b/include/clang/Basic/TokenKinds.def
index 239712c..9942233 100644
--- a/include/clang/Basic/TokenKinds.def
+++ b/include/clang/Basic/TokenKinds.def
@@ -17,6 +17,9 @@
#ifndef TOK
#define TOK(X)
#endif
+#ifndef PUNCTUATOR
+#define PUNCTUATOR(X,Y) TOK(X)
+#endif
#ifndef KEYWORD
#define KEYWORD(X,Y) TOK(kw_ ## X)
#endif
@@ -113,64 +116,63 @@ TOK(wide_string_literal) // L"foo"
TOK(angle_string_literal)// <foo>
// C99 6.4.6: Punctuators.
-TOK(l_square) // [
-TOK(r_square) // ]
-TOK(l_paren) // (
-TOK(r_paren) // )
-TOK(l_brace) // {
-TOK(r_brace) // }
-TOK(period) // .
-TOK(ellipsis) // ...
-TOK(amp) // &
-TOK(ampamp) // &&
-TOK(ampequal) // &=
-TOK(star) // *
-TOK(starequal) // *=
-TOK(plus) // +
-TOK(plusplus) // ++
-TOK(plusequal) // +=
-TOK(minus) // -
-TOK(arrow) // ->
-TOK(minusminus) // --
-TOK(minusequal) // -=
-TOK(tilde) // ~
-TOK(exclaim) // !
-TOK(exclaimequal) // !=
-TOK(slash) // /
-TOK(slashequal) // /=
-TOK(percent) // %
-TOK(percentequal) // %=
-TOK(less) // <
-TOK(lessless) // <<
-TOK(lessequal) // <=
-TOK(lesslessequal) // <<=
-TOK(greater) // >
-TOK(greatergreater) // >>
-TOK(greaterequal) // >=
-TOK(greatergreaterequal) // >>=
-TOK(caret) // ^
-TOK(caretequal) // ^=
-TOK(pipe) // |
-TOK(pipepipe) // ||
-TOK(pipeequal) // |=
-TOK(question) // ?
-TOK(colon) // :
-TOK(semi) // ;
-TOK(equal) // =
-TOK(equalequal) // ==
-TOK(comma) // ,
-TOK(hash) // #
-TOK(hashhash) // ##
-TOK(hashat) // #@
+PUNCTUATOR(l_square, "[")
+PUNCTUATOR(r_square, "]")
+PUNCTUATOR(l_paren, "(")
+PUNCTUATOR(r_paren, ")")
+PUNCTUATOR(l_brace, "{")
+PUNCTUATOR(r_brace, "}")
+PUNCTUATOR(period, ".")
+PUNCTUATOR(ellipsis, "...")
+PUNCTUATOR(amp, "&")
+PUNCTUATOR(ampamp, "&&")
+PUNCTUATOR(ampequal, "&=")
+PUNCTUATOR(star, "*")
+PUNCTUATOR(starequal, "*=")
+PUNCTUATOR(plus, "+")
+PUNCTUATOR(plusplus, "++")
+PUNCTUATOR(plusequal, "+=")
+PUNCTUATOR(minus, "-")
+PUNCTUATOR(arrow, "->")
+PUNCTUATOR(minusminus, "--")
+PUNCTUATOR(minusequal, "-=")
+PUNCTUATOR(tilde, "~")
+PUNCTUATOR(exclaim, "!")
+PUNCTUATOR(exclaimequal, "!=")
+PUNCTUATOR(slash, "/")
+PUNCTUATOR(slashequal, "/=")
+PUNCTUATOR(percent, "%")
+PUNCTUATOR(percentequal, "%=")
+PUNCTUATOR(less, "<")
+PUNCTUATOR(lessless, "<<")
+PUNCTUATOR(lessequal, "<=")
+PUNCTUATOR(lesslessequal, "<<=")
+PUNCTUATOR(greater, ">")
+PUNCTUATOR(greatergreater, ">>")
+PUNCTUATOR(greaterequal, ">=")
+PUNCTUATOR(greatergreaterequal, ">>=")
+PUNCTUATOR(caret, "^")
+PUNCTUATOR(caretequal, "^=")
+PUNCTUATOR(pipe, "|")
+PUNCTUATOR(pipepipe, "||")
+PUNCTUATOR(pipeequal, "|=")
+PUNCTUATOR(question, "?")
+PUNCTUATOR(colon, ":")
+PUNCTUATOR(semi, ";")
+PUNCTUATOR(equal, "=")
+PUNCTUATOR(equalequal, "==")
+PUNCTUATOR(comma, ",")
+PUNCTUATOR(hash, "#")
+PUNCTUATOR(hashhash, "##")
+PUNCTUATOR(hashat, "#@")
// C++ Support
-TOK(periodstar) // .*
-TOK(arrowstar) // ->*
-TOK(coloncolon) // ::
+PUNCTUATOR(periodstar, ".*")
+PUNCTUATOR(arrowstar, "->*")
+PUNCTUATOR(coloncolon, "::")
// Objective C support.
-TOK(at) // @
-
+PUNCTUATOR(at, "@")
// C99 6.4.1: Keywords. These turn into kw_* tokens.
// Flags allowed:
@@ -415,4 +417,5 @@ ANNOTATION(template_id) // annotation for a C++ template-id that names a
#undef PPKEYWORD
#undef ALIAS
#undef KEYWORD
+#undef PUNCTUATOR
#undef TOK
diff --git a/include/clang/CodeGen/CodeGenOptions.h b/include/clang/CodeGen/CodeGenOptions.h
index 02679cd..c8fb37b 100644
--- a/include/clang/CodeGen/CodeGenOptions.h
+++ b/include/clang/CodeGen/CodeGenOptions.h
@@ -29,7 +29,9 @@ public:
OnlyAlwaysInlining // Only run the always inlining pass.
};
+ unsigned AsmVerbose : 1; /// -dA, -fverbose-asm.
unsigned DebugInfo : 1; /// Should generate deubg info (-g).
+ unsigned DisableFPElim : 1; /// Set when -fomit-frame-pointer is enabled.
unsigned DisableLLVMOpts : 1; /// Don't run any optimizations, for use in
/// getting .bc files that correspond to the
/// internal state before optimizations are
@@ -38,35 +40,63 @@ public:
unsigned MergeAllConstants : 1; /// Merge identical constants.
unsigned NoCommon : 1; /// Set when -fno-common or C++ is enabled.
unsigned NoImplicitFloat : 1; /// Set when -mno-implicit-float is enabled.
+ unsigned NoZeroInitializedInBSS : 1; /// -fno-zero-initialized-in-bss
unsigned OptimizationLevel : 3; /// The -O[0-4] option specified.
unsigned OptimizeSize : 1; /// If -Os is specified.
- unsigned SimplifyLibCalls : 1; /// Should standard library calls be treated
- /// specially.
+ unsigned SoftFloat : 1; /// -soft-float.
unsigned TimePasses : 1; /// Set when -ftime-report is enabled.
unsigned UnitAtATime : 1; /// Unused. For mirroring GCC optimization
/// selection.
unsigned UnrollLoops : 1; /// Control whether loops are unrolled.
+ unsigned UnwindTables : 1; /// Emit unwind tables.
unsigned VerifyModule : 1; /// Control whether the module should be run
/// through the LLVM Verifier.
- /// Inlining - The kind of inlining to perform.
+ /// The code model to use (-mcmodel).
+ std::string CodeModel;
+
+ /// Enable additional debugging information.
+ std::string DebugPass;
+
+ /// The ABI to use for passing floating point arguments.
+ std::string FloatABI;
+
+ /// The float precision limit to use, if non-empty.
+ std::string LimitFloatPrecision;
+
+ /// The kind of inlining to perform.
InliningMethod Inlining;
+ /// The user provided name for the "main file", if non-empty. This is useful
+ /// in situations where the input file name does not match the original input
+ /// file, for example with -save-temps.
+ std::string MainFileName;
+
+ /// The name of the relocation model to use.
+ std::string RelocationModel;
+
public:
CodeGenOptions() {
+ AsmVerbose = 0;
+ DebugInfo = 0;
+ DisableFPElim = 0;
+ DisableLLVMOpts = 0;
+ DisableRedZone = 0;
+ MergeAllConstants = 1;
+ NoCommon = 0;
+ NoImplicitFloat = 0;
+ NoZeroInitializedInBSS = 0;
OptimizationLevel = 0;
OptimizeSize = 0;
- DebugInfo = 0;
+ UnrollLoops = 0;
+ SoftFloat = 0;
+ TimePasses = 0;
UnitAtATime = 1;
- SimplifyLibCalls = UnrollLoops = 0;
+ UnwindTables = 0;
VerifyModule = 1;
- TimePasses = 0;
- NoCommon = 0;
+
Inlining = NoInlining;
- DisableRedZone = 0;
- NoImplicitFloat = 0;
- MergeAllConstants = 1;
- DisableLLVMOpts = 0;
+ RelocationModel = "pic";
}
};
diff --git a/include/clang/Driver/ArgList.h b/include/clang/Driver/ArgList.h
index 5263108..ab1abff 100644
--- a/include/clang/Driver/ArgList.h
+++ b/include/clang/Driver/ArgList.h
@@ -25,8 +25,67 @@ namespace llvm {
namespace clang {
namespace driver {
class Arg;
+ class ArgList;
class Option;
+ /// arg_iterator - Iterates through arguments stored inside an ArgList.
+ class arg_iterator {
+ /// The current argument.
+ llvm::SmallVectorImpl<Arg*>::const_iterator Current;
+
+ /// The argument list we are iterating over.
+ const ArgList &Args;
+
+ /// Optional filters on the arguments which will be match. Most clients
+ /// should never want to iterate over arguments without filters, so we won't
+ /// bother to factor this into two separate iterator implementations.
+ //
+ // FIXME: Make efficient; the idea is to provide efficient iteration over
+ // all arguments which match a particular id and then just provide an
+ // iterator combinator which takes multiple iterators which can be
+ // efficiently compared and returns them in order.
+ OptSpecifier Id0, Id1, Id2;
+
+ void SkipToNextArg();
+
+ public:
+ typedef const Arg* value_type;
+ typedef const Arg* reference;
+ typedef const Arg* pointer;
+ typedef std::forward_iterator_tag iterator_category;
+ typedef std::ptrdiff_t difference_type;
+
+ arg_iterator(llvm::SmallVectorImpl<Arg*>::const_iterator it,
+ const ArgList &_Args, OptSpecifier _Id0 = 0U,
+ OptSpecifier _Id1 = 0U, OptSpecifier _Id2 = 0U)
+ : Current(it), Args(_Args), Id0(_Id0), Id1(_Id1), Id2(_Id2) {
+ SkipToNextArg();
+ }
+
+ operator const Arg*() { return *Current; }
+ reference operator*() const { return *Current; }
+ pointer operator->() const { return *Current; }
+
+ arg_iterator &operator++() {
+ ++Current;
+ SkipToNextArg();
+ return *this;
+ }
+
+ arg_iterator operator++(int) {
+ arg_iterator tmp(*this);
+ ++(*this);
+ return tmp;
+ }
+
+ friend bool operator==(arg_iterator LHS, arg_iterator RHS) {
+ return LHS.Current == RHS.Current;
+ }
+ friend bool operator!=(arg_iterator LHS, arg_iterator RHS) {
+ return !(LHS == RHS);
+ }
+ };
+
/// ArgList - Ordered collection of driver arguments.
///
/// The ArgList class manages a list of Arg instances as well as
@@ -62,6 +121,10 @@ namespace driver {
unsigned size() const { return Args.size(); }
+ /// @}
+ /// @name Arg Iteration
+ /// @{
+
iterator begin() { return Args.begin(); }
iterator end() { return Args.end(); }
@@ -74,6 +137,18 @@ namespace driver {
const_reverse_iterator rbegin() const { return Args.rbegin(); }
const_reverse_iterator rend() const { return Args.rend(); }
+ arg_iterator filtered_begin(OptSpecifier Id0 = 0U, OptSpecifier Id1 = 0U,
+ OptSpecifier Id2 = 0U) const {
+ return arg_iterator(Args.begin(), *this, Id0, Id1, Id2);
+ }
+ arg_iterator filtered_end() const {
+ return arg_iterator(Args.end(), *this);
+ }
+
+ /// @}
+ /// @name Arg Access
+ /// @{
+
/// hasArg - Does the arg list contain any option matching \arg Id.
///
/// \arg Claim Whether the argument should be claimed, if it exists.
@@ -115,17 +190,13 @@ namespace driver {
void AddLastArg(ArgStringList &Output, OptSpecifier Id0) const;
/// AddAllArgs - Render all arguments matching the given ids.
- void AddAllArgs(ArgStringList &Output, OptSpecifier Id0) const;
void AddAllArgs(ArgStringList &Output, OptSpecifier Id0,
- OptSpecifier Id1) const;
- void AddAllArgs(ArgStringList &Output, OptSpecifier Id0, OptSpecifier Id1,
- OptSpecifier Id2) const;
+ OptSpecifier Id1 = 0U, OptSpecifier Id2 = 0U) const;
/// AddAllArgValues - Render the argument values of all arguments
/// matching the given ids.
- void AddAllArgValues(ArgStringList &Output, OptSpecifier Id0) const;
void AddAllArgValues(ArgStringList &Output, OptSpecifier Id0,
- OptSpecifier Id1) const;
+ OptSpecifier Id1 = 0U, OptSpecifier Id2 = 0U) const;
/// AddAllArgsTranslated - Render all the arguments matching the
/// given ids, but forced to separate args and using the provided
diff --git a/include/clang/Driver/CC1Options.h b/include/clang/Driver/CC1Options.h
index 057022c..4a8bbe5 100644
--- a/include/clang/Driver/CC1Options.h
+++ b/include/clang/Driver/CC1Options.h
@@ -17,8 +17,6 @@ namespace driver {
namespace cc1options {
enum ID {
OPT_INVALID = 0, // This is not an option ID.
- OPT_INPUT, // Reserved ID for input option.
- OPT_UNKNOWN, // Reserved ID for unknown option.
#define OPTION(NAME, ID, KIND, GROUP, ALIAS, FLAGS, PARAM, \
HELPTEXT, METAVAR) OPT_##ID,
#include "clang/Driver/CC1Options.inc"
diff --git a/include/clang/Driver/CC1Options.td b/include/clang/Driver/CC1Options.td
index ef8d847..b34fe03 100644
--- a/include/clang/Driver/CC1Options.td
+++ b/include/clang/Driver/CC1Options.td
@@ -14,13 +14,400 @@
// Include the common option parsing interfaces.
include "OptParser.td"
+//===----------------------------------------------------------------------===//
// Target Options
+//===----------------------------------------------------------------------===//
def target_abi : Separate<"-target-abi">,
HelpText<"Target a particular ABI type">;
-def target_cpu : Separate<"-mcpu">,
- HelpText<"Target a specific cpu type (-mcpu=help for details)">;
-def target_features : Separate<"-target-feature">,
+def mcpu : Separate<"-mcpu">,
+ HelpText<"Target a specific cpu type ('-mcpu help' for details)">;
+def target_feature : Separate<"-target-feature">,
HelpText<"Target specific attributes">;
-def target_triple : Separate<"-triple">,
+def triple : Separate<"-triple">,
HelpText<"Specify target triple (e.g. i686-apple-darwin9)">;
+def triple_EQ : Joined<"-triple=">, Alias<triple>;
+
+//===----------------------------------------------------------------------===//
+// Analyzer Options
+//===----------------------------------------------------------------------===//
+
+def analysis_CFGDump : Flag<"-cfg-dump">,
+ HelpText<"Display Control-Flow Graphs">;
+def analysis_CFGView : Flag<"-cfg-view">,
+ HelpText<"View Control-Flow Graphs using GraphViz">;
+def analysis_DisplayLiveVariables : Flag<"-dump-live-variables">,
+ HelpText<"Print results of live variable analysis">;
+def analysis_SecuritySyntacticChecks : Flag<"-warn-security-syntactic">,
+ HelpText<"Perform quick security checks that require no data flow">;
+def analysis_WarnDeadStores : Flag<"-warn-dead-stores">,
+ HelpText<"Warn about stores to dead variables">;
+def analysis_WarnUninitVals : Flag<"-warn-uninit-values">,
+ HelpText<"Warn about uses of uninitialized variables">;
+def analysis_WarnObjCMethSigs : Flag<"-warn-objc-methodsigs">,
+ HelpText<"Warn about Objective-C method signatures with type incompatibilities">;
+def analysis_WarnObjCDealloc : Flag<"-warn-objc-missing-dealloc">,
+ HelpText<"Warn about Objective-C classes that lack a correct implementation of -dealloc">;
+def analysis_WarnObjCUnusedIvars : Flag<"-warn-objc-unused-ivars">,
+ HelpText<"Warn about private ivars that are never used">;
+def analysis_CheckerCFRef : Flag<"-checker-cfref">,
+ HelpText<"Run the [Core] Foundation reference count checker">;
+def analysis_WarnSizeofPointer : Flag<"-warn-sizeof-pointer">,
+ HelpText<"Warn about unintended use of sizeof() on pointer expressions">;
+def analysis_InlineCall : Flag<"-inline-call">,
+ HelpText<"Experimental transfer function inling callees when its definition is available.">;
+
+def analyzer_store : Separate<"-analyzer-store">,
+ HelpText<"Source Code Analysis - Abstract Memory Store Models">;
+def analyzer_store_EQ : Joined<"-analyzer-store=">, Alias<analyzer_store>;
+
+def analyzer_constraints : Separate<"-analyzer-constraints">,
+ HelpText<"Source Code Analysis - Symbolic Constraint Engines">;
+def analyzer_constraints_EQ : Joined<"-analyzer-constraints=">,
+ Alias<analyzer_constraints>;
+
+def analyzer_output : Separate<"-analyzer-output">,
+ HelpText<"Source Code Analysis - Output Options">;
+def analyzer_output_EQ : Joined<"-analyzer-output=">,
+ Alias<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_display_progress : Flag<"-analyzer-display-progress">,
+ HelpText<"Emit verbose output about the analyzer's progress">;
+def analyzer_experimental_checks : Flag<"-analyzer-experimental-checks">,
+ HelpText<"Use experimental path-sensitive checks">;
+def analyzer_experimental_internal_checks :
+ Flag<"-analyzer-experimental-internal-checks">,
+ HelpText<"Use new default path-sensitive checks currently in testing">;
+def analyze_function : Separate<"-analyze-function">,
+ HelpText<"Run analysis on specific function">;
+def analyze_function_EQ : Joined<"-analyze-function=">, Alias<analyze_function>;
+def analyzer_eagerly_assume : Flag<"-analyzer-eagerly-assume">,
+ HelpText<"Eagerly assume the truth/falseness of some symbolic constraints">;
+def analyzer_no_purge_dead : Flag<"-analyzer-no-purge-dead">,
+ HelpText<"Don't remove dead symbols, bindings, and constraints before processing a statement">;
+def trim_egraph : Flag<"-trim-egraph">,
+ HelpText<"Only show error-related paths in the analysis graph">;
+def analyzer_viz_egraph_graphviz : Flag<"-analyzer-viz-egraph-graphviz">,
+ HelpText<"Display exploded graph using GraphViz">;
+def analyzer_viz_egraph_ubigraph : Flag<"-analyzer-viz-egraph-ubigraph">,
+ HelpText<"Display exploded graph using Ubigraph">;
+
+//===----------------------------------------------------------------------===//
+// CodeGen Options
+//===----------------------------------------------------------------------===//
+
+def disable_llvm_optzns : Flag<"-disable-llvm-optzns">,
+ HelpText<"Don't run LLVM optimization passes">;
+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 fno_common : Flag<"-fno-common">,
+ HelpText<"Compile common globals like normal definitions">;
+def no_implicit_float : Flag<"-no-implicit-float">,
+ HelpText<"Don't generate implicit floating point instructions (x86-only)">;
+def fno_merge_all_constants : Flag<"-fno-merge-all-constants">,
+ HelpText<"Disallow merging of constants.">;
+def masm_verbose : Flag<"-masm-verbose">,
+ HelpText<"Generate verbose assembly output">;
+def mcode_model : Separate<"-mcode-model">,
+ HelpText<"The code model to use">;
+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">,
+ 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">,
+ HelpText<"Use software floating point">;
+def mrelocation_model : Separate<"-mrelocation-model">,
+ HelpText<"The relocation model to use">;
+def munwind_tables : Flag<"-munwind-tables">,
+ HelpText<"Generate unwinding tables for all functions">;
+def O : Joined<"-O">, HelpText<"Optimization level">;
+def Os : Flag<"-Os">, HelpText<"Optimize for size">;
+
+//===----------------------------------------------------------------------===//
+// Dependency Output Options
+//===----------------------------------------------------------------------===//
+
+def dependency_file : Separate<"-dependency-file">,
+ HelpText<"Filename (or -) to write dependency output to">;
+def sys_header_deps : Flag<"-sys-header-deps">,
+ HelpText<"Include system headers in dependency output">;
+def MT : Separate<"-MT">, HelpText<"Specify target for dependency">;
+def MP : Flag<"-MP">,
+ HelpText<"Create phony target for each dependency (other than main file)">;
+
+//===----------------------------------------------------------------------===//
+// Diagnostic Options
+//===----------------------------------------------------------------------===//
+
+def dump_build_information : Separate<"-dump-build-information">,
+ 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">;
+def fno_show_source_location : Flag<"-fno-show-source-location">,
+ HelpText<"Do not include source location information with diagnostics">;
+def fno_caret_diagnostics : Flag<"-fno-caret-diagnostics">,
+ HelpText<"Do not include source line and caret with diagnostics">;
+def fno_diagnostics_fixit_info : Flag<"-fno-diagnostics-fixit-info">,
+ HelpText<"Do not include fixit information in diagnostics">;
+def w : Flag<"-w">, HelpText<"Suppress all warnings">;
+def pedantic : Flag<"-pedantic">;
+def pedantic_errors : Flag<"-pedantic-errors">;
+
+// This gets all -W options, including -Werror, -W[no-]system-headers, etc. The
+// driver has stripped off -Wa,foo etc. The driver has also translated -W to
+// -Wextra, so we don't need to worry about it.
+def W : Joined<"-W">;
+
+def fdiagnostics_print_source_range_info : Flag<"-fdiagnostics-print-source-range-info">,
+ 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">,
+ 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">;
+def Wno_rewrite_macros : Flag<"-Wno-rewrite-macros">,
+ HelpText<"Silence ObjC rewriting warnings">;
+def verify : Flag<"-verify">,
+ HelpText<"Verify emitted diagnostics and warnings">;
+
+//===----------------------------------------------------------------------===//
+// Frontend Options
+//===----------------------------------------------------------------------===//
+
+def code_completion_at : Separate<"-code-completion-at">,
+ MetaVarName<"file:line:column">,
+ HelpText<"Dump code-completion information at a location">;
+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">;
+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 x : Separate<"-x">, HelpText<"Input language type">;
+def cxx_inheritance_view : Separate<"-cxx-inheritance-view">,
+ MetaVarName<"class name">,
+ HelpText<"View C++ inheritance for a specified class">;
+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 plugin : Separate<"-plugin">,
+ HelpText<"Use the named plugin action (use \"help\" to list available options)">;
+
+def Action_Group : OptionGroup<"<action group>">;
+let Group = Action_Group in {
+
+def Eonly : Flag<"-Eonly">,
+ HelpText<"Just run preprocessor, no output (for timings)">;
+def E : Flag<"-E">,
+ HelpText<"Run preprocessor, emit preprocessed file">;
+def dump_raw_tokens : Flag<"-dump-raw-tokens">,
+ HelpText<"Lex file in raw mode and dump raw tokens">;
+def analyze : Flag<"-analyze">,
+ HelpText<"Run static analysis engine">;
+def dump_tokens : Flag<"-dump-tokens">,
+ HelpText<"Run preprocessor, dump internal rep of tokens">;
+def parse_noop : Flag<"-parse-noop">,
+ HelpText<"Run parser with noop callbacks (for timings)">;
+def fsyntax_only : Flag<"-fsyntax-only">,
+ HelpText<"Run parser and perform semantic analysis">;
+def fixit : Flag<"-fixit">,
+ HelpText<"Apply fix-it advice to the input source">;
+def parse_print_callbacks : Flag<"-parse-print-callbacks">,
+ HelpText<"Run parser and print each callback invoked">;
+def emit_html : Flag<"-emit-html">,
+ HelpText<"Output input source as HTML">;
+def ast_print : Flag<"-ast-print">,
+ HelpText<"Build ASTs and then pretty-print them">;
+def ast_print_xml : Flag<"-ast-print-xml">,
+ HelpText<"Build ASTs and then print them in XML format">;
+def ast_dump : Flag<"-ast-dump">,
+ HelpText<"Build ASTs and then debug dump them">;
+def ast_view : Flag<"-ast-view">,
+ HelpText<"Build ASTs and view them with GraphViz">;
+def print_decl_contexts : Flag<"-print-decl-contexts">,
+ HelpText<"Print DeclContexts and their Decls">;
+def dump_record_layouts : Flag<"-dump-record-layouts">,
+ HelpText<"Dump record layout information">;
+def emit_pth : Flag<"-emit-pth">,
+ HelpText<"Generate pre-tokenized header file">;
+def emit_pch : Flag<"-emit-pch">,
+ HelpText<"Generate pre-compiled header file">;
+def S : Flag<"-S">,
+ HelpText<"Emit native assembly code">;
+def emit_llvm : Flag<"-emit-llvm">,
+ HelpText<"Build ASTs then convert to LLVM, emit .ll file">;
+def emit_llvm_bc : Flag<"-emit-llvm-bc">,
+ HelpText<"Build ASTs then convert to LLVM, emit .bc file">;
+def emit_llvm_only : Flag<"-emit-llvm-only">,
+ HelpText<"Build ASTs and convert to LLVM, discarding output">;
+def rewrite_test : Flag<"-rewrite-test">,
+ HelpText<"Rewriter playground">;
+def rewrite_objc : Flag<"-rewrite-objc">,
+ HelpText<"Rewrite ObjC into C (code rewriter example)">;
+def rewrite_macros : Flag<"-rewrite-macros">,
+ HelpText<"Expand macros without full preprocessing">;
+def rewrite_blocks : Flag<"-rewrite-blocks">,
+ HelpText<"Rewrite Blocks to C">;
+
+}
+
+def relocatable_pch : Flag<"-relocatable-pch">,
+ HelpText<"Whether to build a relocatable precompiled header">;
+def print_stats : Flag<"-print-stats">,
+ HelpText<"Print performance metrics and statistics">;
+def ftime_report : Flag<"-ftime-report">,
+ HelpText<"Print the amount of time each phase of compilation takes">;
+
+//===----------------------------------------------------------------------===//
+// Language Options
+//===----------------------------------------------------------------------===//
+
+def fno_builtin : Flag<"-fno-builtin">,
+ HelpText<"Disable implicit builtin knowledge of functions">;
+def faltivec : Flag<"-faltivec">,
+ HelpText<"Enable AltiVec vector initializer syntax">;
+def faccess_control : Flag<"-faccess-control">,
+ HelpText<"Enable C++ access control">;
+def fdollars_in_identifiers : Flag<"-fdollars-in-identifiers">,
+ HelpText<"Allow '$' in identifiers">;
+def femit_all_decls : Flag<"-femit-all-decls">,
+ HelpText<"Emit all declarations, even if unused">;
+def fblocks : Flag<"-fblocks">,
+ HelpText<"enable the 'blocks' language feature">;
+def fheinous_gnu_extensions : Flag<"-fheinous-gnu-extensions">;
+def fexceptions : Flag<"-fexceptions">,
+ HelpText<"Enable support for exception handling">;
+def ffreestanding : Flag<"-ffreestanding">,
+ HelpText<"Assert that the compilation takes place in a freestanding environment">;
+def fgnu_runtime : Flag<"-fgnu-runtime">,
+ HelpText<"Generate output compatible with the standard GNU Objective-C runtime">;
+def std_EQ : Joined<"-std=">,
+ HelpText<"Language standard to compile for">;
+def fms_extensions : Flag<"-fms-extensions">,
+ HelpText<"Accept some non-standard constructs used in Microsoft header files ">;
+def main_file_name : Separate<"-main-file-name">,
+ HelpText<"Main file name to use for debug info">;
+def fno_elide_constructors : Flag<"-fno-elide-constructors">,
+ HelpText<"Disable C++ copy constructor elision">;
+def fno_lax_vector_conversions : Flag<"-fno-lax-vector-conversions">,
+ HelpText<"Disallow implicit conversions between vectors with a different number of elements or different element types">;
+def fno_math_errno : Flag<"-fno-math-errno">,
+ HelpText<"Don't require math functions to respect errno">;
+def fno_signed_char : Flag<"-fno-signed-char">,
+ HelpText<"Char is unsigned">;
+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">,
+ HelpText<"Specify the class to use for constant Objective-C string objects.">;
+def fobjc_gc : Flag<"-fobjc-gc">,
+ HelpText<"Enable Objective-C garbage collection">;
+def fobjc_gc_only : Flag<"-fobjc-gc-only">,
+ HelpText<"Use GC exclusively for Objective-C related memory management">;
+def print_ivar_layout : Flag<"-print-ivar-layout">,
+ HelpText<"Enable Objective-C Ivar layout bitmap print trace">;
+def fobjc_nonfragile_abi : Flag<"-fobjc-nonfragile-abi">,
+ HelpText<"enable objective-c's nonfragile abi">;
+def ftrapv : Flag<"-ftrapv">,
+ HelpText<"Trap on integer overflow">;
+def pic_level : Separate<"-pic-level">,
+ HelpText<"-Value for __PIC__">;
+def pthread : Flag<"-pthread">,
+ HelpText<"Support POSIX threads in generated code">;
+def fpascal_strings : Flag<"-fpascal-strings">,
+ HelpText<"Recognize and construct Pascal-style string literals">;
+def fno_rtti : Flag<"-fno-rtti">,
+ HelpText<"Disable generation of rtti information">;
+def fshort_wchar : Flag<"-fshort-wchar">,
+ HelpText<"Force wchar_t to be a short unsigned int">;
+def static_define : Flag<"-static-define">,
+ HelpText<"Should __STATIC__ be defined">;
+def stack_protector : Separate<"-stack-protector">,
+ HelpText<"Enable stack protectors">;
+def fvisibility : Separate<"-fvisibility">,
+ HelpText<"Default symbol visibility">;
+def ftemplate_depth : Separate<"-ftemplate-depth">,
+ HelpText<"Maximum depth of recursive template instantiation">;
+def trigraphs : Flag<"-trigraphs">,
+ HelpText<"Process trigraph sequences">;
+def fwritable_strings : Flag<"-fwritable-strings">,
+ HelpText<"Store string literals as writable data">;
+
+//===----------------------------------------------------------------------===//
+// Header Search Options
+//===----------------------------------------------------------------------===//
+
+def nostdinc : Flag<"-nostdinc">,
+ HelpText<"Disable standard #include directories">;
+def nobuiltininc : Flag<"-nobuiltininc">,
+ HelpText<"Disable builtin #include directories">;
+def F : JoinedOrSeparate<"-F">, MetaVarName<"directory">,
+ HelpText<"Add directory to framework include search path">;
+def I : JoinedOrSeparate<"-I">, MetaVarName<"directory">,
+ HelpText<"Add directory to include search path">;
+def idirafter : Separate<"-idirafter">, MetaVarName<"directory">,
+ HelpText<"Add directory to AFTER include search path">;
+def iquote : Separate<"-iquote">, MetaVarName<"directory">,
+ HelpText<"Add directory to QUOTE include search path">;
+def isystem : Separate<"-isystem">, MetaVarName<"directory">,
+ HelpText<"Add directory to SYSTEM include search path">;
+def iprefix : Separate<"-iprefix">, MetaVarName<"prefix">,
+ HelpText<"Set the -iwithprefix/-iwithprefixbefore prefix">;
+def iwithprefix : Separate<"-iwithprefix">, MetaVarName<"dir">,
+ HelpText<"Set directory to SYSTEM include search path with prefix">;
+def iwithprefixbefore : Separate<"-iwithprefixbefore">, MetaVarName<"dir">,
+ HelpText<"Set directory to include search path with prefix">;
+def isysroot : Separate<"-isysroot">, MetaVarName<"dir">,
+ HelpText<"Set the system root directory (usually /)">;
+def v : Flag<"-v">, HelpText<"Enable verbose output">;
+
+//===----------------------------------------------------------------------===//
+// Preprocessor Options
+//===----------------------------------------------------------------------===//
+
+def D : JoinedOrSeparate<"-D">, MetaVarName<"macro">,
+ HelpText<"Predefine the specified macro">;
+def include_ : Separate<"-include">, MetaVarName<"file">, EnumName<"include">,
+ HelpText<"Include file before parsing">;
+def imacros : Separate<"-imacros">, MetaVarName<"file">,
+ HelpText<"Include macros from file before parsing">;
+def include_pch : Separate<"-include-pch">, MetaVarName<"file">,
+ HelpText<"Include precompiled header file">;
+def include_pth : Separate<"-include-pth">, MetaVarName<"file">,
+ HelpText<"Include file before parsing">;
+def token_cache : Separate<"-token-cache">, MetaVarName<"path">,
+ HelpText<"Use specified token cache file">;
+def U : JoinedOrSeparate<"-U">, MetaVarName<"macro">,
+ HelpText<"Undefine the specified macro">;
+def undef : Flag<"-undef">, MetaVarName<"macro">,
+ HelpText<"undef all system defines">;
+
+//===----------------------------------------------------------------------===//
+// Preprocessed Output Options
+//===----------------------------------------------------------------------===//
+
+def P : Flag<"-P">,
+ HelpText<"Disable linemarker output in -E mode">;
+def C : Flag<"-C">,
+ HelpText<"Enable comment output in -E mode">;
+def CC : Flag<"-CC">,
+ HelpText<"Enable comment output in -E mode, even from macro expansions">;
+def dM : Flag<"-dM">,
+ HelpText<"Print macro definitions in -E mode instead of normal output">;
+def dD : Flag<"-dD">,
+ HelpText<"Print macro definitions in -E mode in addition to normal output">;
diff --git a/include/clang/Driver/Makefile b/include/clang/Driver/Makefile
index c0f2cc7..18f3e58 100644
--- a/include/clang/Driver/Makefile
+++ b/include/clang/Driver/Makefile
@@ -5,11 +5,11 @@ TABLEGEN_INC_FILES_COMMON = 1
include $(LEVEL)/Makefile.common
-$(ObjDir)/Options.inc.tmp : Options.td OptParser.td $(ObjDir)/.dir
+$(ObjDir)/Options.inc.tmp : Options.td OptParser.td $(TBLGEN) $(ObjDir)/.dir
$(Echo) "Building Clang Driver Option tables with tblgen"
$(Verb) $(TableGen) -gen-opt-parser-defs -o $(call SYSPATH, $@) $<
-$(ObjDir)/CC1Options.inc.tmp : CC1Options.td OptParser.td $(ObjDir)/.dir
+$(ObjDir)/CC1Options.inc.tmp : CC1Options.td OptParser.td $(TBLGEN) $(ObjDir)/.dir
$(Echo) "Building Clang CC1 Option tables with tblgen"
$(Verb) $(TableGen) -gen-opt-parser-defs -o $(call SYSPATH, $@) $<
diff --git a/include/clang/Driver/OptParser.td b/include/clang/Driver/OptParser.td
index 70b59c6..f5b6980 100644
--- a/include/clang/Driver/OptParser.td
+++ b/include/clang/Driver/OptParser.td
@@ -14,14 +14,20 @@
// Define the kinds of options.
-class OptionKind<string name, int predecence = 0> {
+class OptionKind<string name, int predecence = 0, bit sentinel = 0> {
string Name = name;
// The kind precedence, kinds with lower precedence are matched first.
int Precedence = predecence;
+ // Indicate a sentinel option.
+ bit Sentinel = sentinel;
}
// An option group.
def KIND_GROUP : OptionKind<"Group">;
+// The input option kind.
+def KIND_INPUT : OptionKind<"Input", 1, 1>;
+// The unknown option kind.
+def KIND_UNKNOWN : OptionKind<"Unknown", 2, 1>;
// A flag with no values.
def KIND_FLAG : OptionKind<"Flag">;
// An option which prefixes its (single) value.
@@ -114,3 +120,10 @@ class Flags<list<OptionFlag> flags> { list<OptionFlag> Flags = flags; }
class Group<OptionGroup group> { OptionGroup Group = group; }
class HelpText<string text> { string HelpText = text; }
class MetaVarName<string name> { string MetaVarName = name; }
+
+// Predefined options.
+
+// FIXME: Have generator validate that these appear in correct position (and
+// aren't duplicated).
+def INPUT : Option<"<input>", KIND_INPUT>, Flags<[DriverOption]>;
+def UNKNOWN : Option<"<unknown>", KIND_UNKNOWN>;
diff --git a/include/clang/Driver/OptSpecifier.h b/include/clang/Driver/OptSpecifier.h
index c38b36c..bb1cd17 100644
--- a/include/clang/Driver/OptSpecifier.h
+++ b/include/clang/Driver/OptSpecifier.h
@@ -22,9 +22,12 @@ namespace driver {
explicit OptSpecifier(bool); // DO NOT IMPLEMENT
public:
+ OptSpecifier() : ID(0) {}
/*implicit*/ OptSpecifier(unsigned _ID) : ID(_ID) {}
/*implicit*/ OptSpecifier(const Option *Opt);
+ bool isValid() const { return ID != 0; }
+
unsigned getID() const { return ID; }
bool operator==(OptSpecifier Opt) const { return ID == Opt.getID(); }
diff --git a/include/clang/Driver/Options.h b/include/clang/Driver/Options.h
index b05d5af..ac312cd 100644
--- a/include/clang/Driver/Options.h
+++ b/include/clang/Driver/Options.h
@@ -17,8 +17,6 @@ namespace driver {
namespace options {
enum ID {
OPT_INVALID = 0, // This is not an option ID.
- OPT_INPUT, // Reserved ID for input option.
- OPT_UNKNOWN, // Reserved ID for unknown option.
#define OPTION(NAME, ID, KIND, GROUP, ALIAS, FLAGS, PARAM, \
HELPTEXT, METAVAR) OPT_##ID,
#include "clang/Driver/Options.inc"
diff --git a/include/clang/Frontend/ASTConsumers.h b/include/clang/Frontend/ASTConsumers.h
index 0e7d55e..26efa97 100644
--- a/include/clang/Frontend/ASTConsumers.h
+++ b/include/clang/Frontend/ASTConsumers.h
@@ -83,6 +83,7 @@ ASTConsumer *CreateBackendConsumer(BackendAction Action,
const LangOptions &Features,
const CodeGenOptions &CodeGenOpts,
const TargetOptions &TargetOpts,
+ bool TimePasses,
const std::string &ModuleID,
llvm::raw_ostream *OS,
llvm::LLVMContext& C);
diff --git a/include/clang/Frontend/ASTUnit.h b/include/clang/Frontend/ASTUnit.h
index 7dfabba..04dc5ed 100644
--- a/include/clang/Frontend/ASTUnit.h
+++ b/include/clang/Frontend/ASTUnit.h
@@ -22,16 +22,17 @@
#include <string>
namespace clang {
- class FileManager;
- class FileEntry;
- class SourceManager;
- class Diagnostic;
- class TextDiagnosticBuffer;
- class HeaderSearch;
- class TargetInfo;
- class Preprocessor;
- class ASTContext;
- class Decl;
+class ASTContext;
+class CompilerInvocation;
+class Decl;
+class Diagnostic;
+class FileEntry;
+class FileManager;
+class HeaderSearch;
+class Preprocessor;
+class SourceManager;
+class TargetInfo;
+class TextDiagnosticBuffer;
using namespace idx;
@@ -92,21 +93,35 @@ public:
///
/// \param Filename - The PCH file to load.
///
- /// \param diagClient - The diagnostics client to use. Specify NULL
+ /// \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 FileMgr - The FileManager to use.
- ///
/// \param ErrMsg - Error message to report if the PCH file could not be
/// loaded.
///
/// \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,
+ DiagnosticClient *DiagClient = NULL,
bool OnlyLocalDecls = false,
bool UseBumpAllocator = false);
+
+ /// LoadFromCompilerInvocation - Create an ASTUnit from a source file, via a
+ /// CompilerInvocation object.
+ ///
+ /// \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.
+ //
+ // 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);
+
};
} // namespace clang
diff --git a/include/clang/Frontend/AnalysisConsumer.h b/include/clang/Frontend/AnalysisConsumer.h
index 7a32433..24fed6e 100644
--- a/include/clang/Frontend/AnalysisConsumer.h
+++ b/include/clang/Frontend/AnalysisConsumer.h
@@ -77,7 +77,7 @@ public:
AnalyzeAll = 0;
AnalyzerDisplayProgress = 0;
EagerlyAssume = 0;
- PurgeDead = 0;
+ PurgeDead = 1;
TrimGraph = 0;
VisualizeEGDot = 0;
VisualizeEGUbi = 0;
diff --git a/include/clang/Frontend/CommandLineSourceLoc.h b/include/clang/Frontend/CommandLineSourceLoc.h
index d5a0598..bea468b 100644
--- a/include/clang/Frontend/CommandLineSourceLoc.h
+++ b/include/clang/Frontend/CommandLineSourceLoc.h
@@ -16,7 +16,7 @@
#define LLVM_CLANG_FRONTEND_COMMANDLINESOURCELOC_H
#include "llvm/Support/CommandLine.h"
-#include <cstdio>
+#include "llvm/Support/raw_ostream.h"
namespace clang {
@@ -25,6 +25,23 @@ struct ParsedSourceLocation {
std::string FileName;
unsigned Line;
unsigned Column;
+
+public:
+ /// Construct a parsed source location from a string; the Filename is empty on
+ /// error.
+ static ParsedSourceLocation FromString(llvm::StringRef Str) {
+ ParsedSourceLocation PSL;
+ std::pair<llvm::StringRef, llvm::StringRef> ColSplit = Str.rsplit(':');
+ std::pair<llvm::StringRef, llvm::StringRef> LineSplit =
+ ColSplit.first.rsplit(':');
+
+ // If both tail splits were valid integers, return success.
+ if (!ColSplit.second.getAsInteger(10, PSL.Column) &&
+ !LineSplit.second.getAsInteger(10, PSL.Line))
+ PSL.FileName = LineSplit.first;
+
+ return PSL;
+ }
};
}
@@ -48,35 +65,13 @@ namespace llvm {
clang::ParsedSourceLocation &Val) {
using namespace clang;
- const char *ExpectedFormat
- = "source location must be of the form filename:line:column";
- StringRef::size_type SecondColon = ArgValue.rfind(':');
- if (SecondColon == std::string::npos) {
- std::fprintf(stderr, "%s\n", ExpectedFormat);
- return true;
- }
-
- unsigned Column;
- if (ArgValue.substr(SecondColon + 1).getAsInteger(10, Column)) {
- std::fprintf(stderr, "%s\n", ExpectedFormat);
- return true;
- }
- ArgValue = ArgValue.substr(0, SecondColon);
-
- StringRef::size_type FirstColon = ArgValue.rfind(':');
- if (FirstColon == std::string::npos) {
- std::fprintf(stderr, "%s\n", ExpectedFormat);
- return true;
- }
- unsigned Line;
- if (ArgValue.substr(FirstColon + 1).getAsInteger(10, Line)) {
- std::fprintf(stderr, "%s\n", ExpectedFormat);
+ Val = ParsedSourceLocation::FromString(ArgValue);
+ if (Val.FileName.empty()) {
+ errs() << "error: "
+ << "source location must be of the form filename:line:column\n";
return true;
}
- Val.FileName = ArgValue.substr(0, FirstColon);
- Val.Line = Line;
- Val.Column = Column;
return false;
}
}
diff --git a/include/clang/Frontend/CompilerInstance.h b/include/clang/Frontend/CompilerInstance.h
index ed28050..d7e7d99 100644
--- a/include/clang/Frontend/CompilerInstance.h
+++ b/include/clang/Frontend/CompilerInstance.h
@@ -21,6 +21,7 @@ namespace llvm {
class LLVMContext;
class raw_ostream;
class raw_fd_ostream;
+class Timer;
}
namespace clang {
@@ -89,6 +90,9 @@ class CompilerInstance {
/// The code completion consumer.
llvm::OwningPtr<CodeCompleteConsumer> CompletionConsumer;
+ /// The frontend timer
+ llvm::OwningPtr<llvm::Timer> FrontendTimer;
+
/// The list of active output files.
std::list< std::pair<std::string, llvm::raw_ostream*> > OutputFiles;
@@ -367,6 +371,17 @@ public:
void setCodeCompletionConsumer(CodeCompleteConsumer *Value);
/// }
+ /// @name Frontend timer
+ /// {
+
+ bool hasFrontendTimer() const { return FrontendTimer != 0; }
+
+ llvm::Timer &getFrontendTimer() const {
+ assert(FrontendTimer && "Compiler instance has no frontend timer!");
+ return *FrontendTimer;
+ }
+
+ /// }
/// @name Output Files
/// {
@@ -462,6 +477,9 @@ public:
bool UseDebugPrinter, bool ShowMacros,
llvm::raw_ostream &OS);
+ /// Create the frontend timer and replace any existing one with it.
+ void createFrontendTimer();
+
/// Create the default output file (from the invocation's options) and add it
/// to the list of tracked output files.
llvm::raw_fd_ostream *
diff --git a/include/clang/Frontend/CompilerInvocation.h b/include/clang/Frontend/CompilerInvocation.h
index 9d068c5..e7c51aa 100644
--- a/include/clang/Frontend/CompilerInvocation.h
+++ b/include/clang/Frontend/CompilerInvocation.h
@@ -31,6 +31,8 @@ namespace llvm {
namespace clang {
+class Diagnostic;
+
/// CompilerInvocation - Helper class for holding the data necessary to invoke
/// the compiler.
///
@@ -77,12 +79,18 @@ public:
/// CreateFromArgs - Create a compiler invocation from a list of input
/// options.
///
- /// FIXME: Documenting error behavior.
- ///
/// \param Res [out] - The resulting invocation.
- /// \param Args - The input argument strings.
- static void CreateFromArgs(CompilerInvocation &Res,
- const llvm::SmallVectorImpl<llvm::StringRef> &Args);
+ /// \param ArgBegin - The first element in the argument vector.
+ /// \param ArgEnd - The last element in the argument vector.
+ /// \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);
/// toArgs - Convert the CompilerInvocation to a list of strings suitable for
/// passing to CreateFromArgs.
diff --git a/include/clang/Frontend/DeclXML.def b/include/clang/Frontend/DeclXML.def
index 8b80d1d..c750492 100644
--- a/include/clang/Frontend/DeclXML.def
+++ b/include/clang/Frontend/DeclXML.def
@@ -7,46 +7,46 @@
//
//===----------------------------------------------------------------------===//
//
-// This file defines the XML statement database structure as written in
-// <TranslationUnit> sub-nodes of the XML document.
+// This file defines the XML statement database structure as written in
+// <TranslationUnit> sub-nodes of the XML document.
// The semantics of the attributes and enums are mostly self-documenting
// by looking at the appropriate internally used functions and values.
// The following macros are used:
//
-// NODE_XML( CLASS, NAME ) - A node of name NAME denotes a concrete
-// statement of class CLASS where CLASS is a class name used internally by clang.
-// After a NODE_XML the definition of all (optional) attributes of that statement
+// NODE_XML( CLASS, NAME ) - A node of name NAME denotes a concrete
+// statement of class CLASS where CLASS is a class name used internally by clang.
+// After a NODE_XML the definition of all (optional) attributes of that statement
// node and possible sub-nodes follows.
//
// END_NODE_XML - Closes the attribute definition of the current node.
//
-// ID_ATTRIBUTE_XML - Some statement nodes have an "id" attribute containing a
-// string, which value uniquely identify that statement. Other nodes may refer
+// ID_ATTRIBUTE_XML - Some statement nodes have an "id" attribute containing a
+// string, which value uniquely identify that statement. Other nodes may refer
// by reference attributes to this value (currently used only for Label).
//
// TYPE_ATTRIBUTE_XML( FN ) - Type nodes refer to the result type id of an
// expression by a "type" attribute. FN is internally used by clang.
-//
-// ATTRIBUTE_XML( FN, NAME ) - An attribute named NAME. FN is internally
+//
+// ATTRIBUTE_XML( FN, NAME ) - An attribute named NAME. FN is internally
// used by clang. A boolean attribute have the values "0" or "1".
//
-// ATTRIBUTE_SPECIAL_XML( FN, NAME ) - An attribute named NAME which deserves
-// a special handling. See the appropriate documentations.
+// ATTRIBUTE_SPECIAL_XML( FN, NAME ) - An attribute named NAME which deserves
+// a special handling. See the appropriate documentations.
//
// ATTRIBUTE_FILE_LOCATION_XML - A bunch of attributes denoting the location of
// a statement in the source file(s).
//
-// ATTRIBUTE_OPT_XML( FN, NAME ) - An optional attribute named NAME.
-// Optional attributes are omitted for boolean types, if the value is false,
-// for integral types, if the value is null and for strings,
+// ATTRIBUTE_OPT_XML( FN, NAME ) - An optional attribute named NAME.
+// Optional attributes are omitted for boolean types, if the value is false,
+// for integral types, if the value is null and for strings,
// if the value is the empty string. FN is internally used by clang.
//
// ATTRIBUTE_ENUM[_OPT]_XML( FN, NAME ) - An attribute named NAME. The value
-// is an enumeration defined with ENUM_XML macros immediately following after
-// that macro. An optional attribute is ommited, if the particular enum is the
+// is an enumeration defined with ENUM_XML macros immediately following after
+// that macro. An optional attribute is ommited, if the particular enum is the
// empty string. FN is internally used by clang.
-//
-// ENUM_XML( VALUE, NAME ) - An enumeration element named NAME. VALUE is
+//
+// ENUM_XML( VALUE, NAME ) - An enumeration element named NAME. VALUE is
// internally used by clang.
//
// END_ENUM_XML - Closes the enumeration definition of the current attribute.
@@ -55,7 +55,7 @@
//
// SUB_NODE_OPT_XML( CLASS ) - An optional sub-node of class CLASS or its sub-classes.
//
-// SUB_NODE_SEQUENCE_XML( CLASS ) - Zero or more sub-nodes of class CLASS or
+// SUB_NODE_SEQUENCE_XML( CLASS ) - Zero or more sub-nodes of class CLASS or
// its sub-classes.
//
//===----------------------------------------------------------------------===//
@@ -114,8 +114,8 @@ NODE_XML(CXXMethodDecl, "CXXMethodDecl")
TYPE_ATTRIBUTE_XML(getType()->getAs<FunctionType>()->getResultType())
ATTRIBUTE_XML(getType()->getAs<FunctionType>(), "function_type")
ATTRIBUTE_OPT_XML(isInlineSpecified(), "inline")
- ATTRIBUTE_OPT_XML(isStatic(), "static")
- ATTRIBUTE_OPT_XML(isVirtual(), "virtual")
+ ATTRIBUTE_OPT_XML(isStatic(), "static")
+ ATTRIBUTE_OPT_XML(isVirtual(), "virtual")
ATTRIBUTE_XML(getNumParams(), "num_args")
SUB_NODE_SEQUENCE_XML(ParmVarDecl)
//SUB_NODE_OPT_XML("Body")
@@ -124,7 +124,7 @@ END_NODE_XML
//NODE_XML("Body")
// SUB_NODE_XML(Stmt)
//END_NODE_XML
-
+
NODE_XML(NamespaceDecl, "Namespace")
ID_ATTRIBUTE_XML
ATTRIBUTE_FILE_LOCATION_XML
@@ -152,7 +152,7 @@ NODE_XML(RecordDecl, "Record")
ATTRIBUTE_XML(getDeclContext(), "context")
ATTRIBUTE_XML(getNameAsString(), "name")
ATTRIBUTE_OPT_XML(isDefinition() == false, "forward")
- ATTRIBUTE_XML(getTypeForDecl(), "type") // refers to the type this decl creates
+ ATTRIBUTE_XML(getTypeForDecl(), "type") // refers to the type this decl creates
SUB_NODE_SEQUENCE_XML(FieldDecl)
END_NODE_XML
@@ -162,7 +162,7 @@ NODE_XML(EnumDecl, "Enum")
ATTRIBUTE_XML(getDeclContext(), "context")
ATTRIBUTE_XML(getNameAsString(), "name")
ATTRIBUTE_OPT_XML(isDefinition() == false, "forward")
- ATTRIBUTE_SPECIAL_XML(getIntegerType(), "type") // is NULL in pure declarations thus deserves special handling
+ ATTRIBUTE_SPECIAL_XML(getIntegerType(), "type") // is NULL in pure declarations thus deserves special handling
SUB_NODE_SEQUENCE_XML(EnumConstantDecl) // only present in definition
END_NODE_XML
@@ -209,7 +209,7 @@ NODE_XML(VarDecl, "Var")
ENUM_XML(VarDecl::Static, "static")
ENUM_XML(VarDecl::PrivateExtern, "__private_extern__")
END_ENUM_XML
- SUB_NODE_OPT_XML(Expr) // init expr
+ SUB_NODE_OPT_XML(Expr) // init expr
END_NODE_XML
NODE_XML(ParmVarDecl, "ParmVar")
@@ -218,7 +218,7 @@ NODE_XML(ParmVarDecl, "ParmVar")
ATTRIBUTE_XML(getDeclContext(), "context")
ATTRIBUTE_XML(getNameAsString(), "name")
TYPE_ATTRIBUTE_XML(getType())
- SUB_NODE_OPT_XML(Expr) // default argument expression
+ SUB_NODE_OPT_XML(Expr) // default argument expression
END_NODE_XML
NODE_XML(LinkageSpecDecl, "LinkageSpec")
@@ -234,7 +234,7 @@ END_NODE_XML
//===----------------------------------------------------------------------===//
#undef NODE_XML
-#undef ID_ATTRIBUTE_XML
+#undef ID_ATTRIBUTE_XML
#undef TYPE_ATTRIBUTE_XML
#undef ATTRIBUTE_XML
#undef ATTRIBUTE_SPECIAL_XML
@@ -243,8 +243,8 @@ END_NODE_XML
#undef ATTRIBUTE_ENUM_OPT_XML
#undef ATTRIBUTE_FILE_LOCATION_XML
#undef ENUM_XML
-#undef END_ENUM_XML
-#undef END_NODE_XML
+#undef END_ENUM_XML
+#undef END_NODE_XML
#undef SUB_NODE_XML
#undef SUB_NODE_SEQUENCE_XML
#undef SUB_NODE_OPT_XML
diff --git a/include/clang/Frontend/FrontendAction.h b/include/clang/Frontend/FrontendAction.h
index 469ea53..3042767 100644
--- a/include/clang/Frontend/FrontendAction.h
+++ b/include/clang/Frontend/FrontendAction.h
@@ -14,10 +14,6 @@
#include "llvm/ADT/OwningPtr.h"
#include <string>
-namespace llvm {
-class Timer;
-}
-
namespace clang {
class ASTUnit;
class ASTConsumer;
@@ -29,7 +25,6 @@ class FrontendAction {
std::string CurrentFile;
llvm::OwningPtr<ASTUnit> CurrentASTUnit;
CompilerInstance *Instance;
- llvm::Timer *CurrentTimer;
protected:
/// @name Implementation Action Interface
@@ -112,18 +107,6 @@ public:
void setCurrentFile(llvm::StringRef Value, ASTUnit *AST = 0);
/// @}
- /// @name Timing Utilities
- /// @{
-
- llvm::Timer *getCurrentTimer() const {
- return CurrentTimer;
- }
-
- void setCurrentTimer(llvm::Timer *Value) {
- CurrentTimer = Value;
- }
-
- /// @}
/// @name Supported Modes
/// @{
diff --git a/include/clang/Frontend/FrontendOptions.h b/include/clang/Frontend/FrontendOptions.h
index 197a2a0..c1ec8e7 100644
--- a/include/clang/Frontend/FrontendOptions.h
+++ b/include/clang/Frontend/FrontendOptions.h
@@ -107,7 +107,7 @@ public:
public:
FrontendOptions() {
- DebugCodeCompletionPrinter = 0;
+ DebugCodeCompletionPrinter = 1;
DisableFree = 0;
EmptyInputOnly = 0;
ProgramAction = frontend::ParseSyntaxOnly;
diff --git a/include/clang/Frontend/LangStandard.h b/include/clang/Frontend/LangStandard.h
new file mode 100644
index 0000000..441d34f
--- /dev/null
+++ b/include/clang/Frontend/LangStandard.h
@@ -0,0 +1,83 @@
+//===--- LangStandard.h -----------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_FRONTEND_LANGSTANDARD_H
+#define LLVM_CLANG_FRONTEND_LANGSTANDARD_H
+
+#include "llvm/ADT/StringRef.h"
+
+namespace clang {
+
+namespace frontend {
+
+enum LangFeatures {
+ BCPLComment = (1 << 0),
+ C99 = (1 << 1),
+ CPlusPlus = (1 << 2),
+ CPlusPlus0x = (1 << 3),
+ Digraphs = (1 << 4),
+ GNUMode = (1 << 5),
+ HexFloat = (1 << 6),
+ ImplicitInt = (1 << 7)
+};
+
+}
+
+/// LangStandard - Information about the properties of a particular language
+/// standard.
+struct LangStandard {
+ enum Kind {
+#define LANGSTANDARD(id, name, desc, features) \
+ lang_##id,
+#include "clang/Frontend/LangStandards.def"
+ lang_unspecified
+ };
+
+ const char *ShortName;
+ const char *Description;
+ unsigned Flags;
+
+public:
+ /// getName - Get the name of this standard.
+ const char *getName() const { return ShortName; }
+
+ /// getDescription - Get the description of this standard.
+ const char *getDescription() const { return Description; }
+
+ /// hasBCPLComments - Language supports '//' comments.
+ bool hasBCPLComments() const { return Flags & frontend::BCPLComment; }
+
+ /// isC99 - Language is a superset of C99.
+ bool isC99() const { return Flags & frontend::C99; }
+
+ /// isCPlusPlus - Language is a C++ variant.
+ bool isCPlusPlus() const { return Flags & frontend::CPlusPlus; }
+
+ /// isCPlusPlus0x - Language is a C++0x variant.
+ bool isCPlusPlus0x() const { return Flags & frontend::CPlusPlus0x; }
+
+ /// hasDigraphs - Language supports digraphs.
+ bool hasDigraphs() const { return Flags & frontend::Digraphs; }
+
+ /// isGNUMode - Language includes GNU extensions.
+ bool isGNUMode() const { return Flags & frontend::GNUMode; }
+
+ /// hasHexFloats - Language supports hexadecimal float constants.
+ bool hasHexFloats() const { return Flags & frontend::HexFloat; }
+
+ /// hasImplicitInt - Language allows variables to be typed as int implicitly.
+ bool hasImplicitInt() const { return Flags & frontend::ImplicitInt; }
+
+ static const LangStandard &getLangStandardForKind(Kind K);
+ static const LangStandard *getLangStandardForName(llvm::StringRef Name);
+};
+
+} // end namespace clang
+
+#endif
diff --git a/include/clang/Frontend/LangStandards.def b/include/clang/Frontend/LangStandards.def
new file mode 100644
index 0000000..52aa463
--- /dev/null
+++ b/include/clang/Frontend/LangStandards.def
@@ -0,0 +1,83 @@
+//===-- LangStandards.def - Language Standard Data --------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LANGSTANDARD
+#error "LANGSTANDARD must be defined before including this file"
+#endif
+
+/// LANGSTANDARD(IDENT, NAME, DESC, FEATURES)
+///
+/// \param IDENT - The name of the standard as a C++ identifier.
+/// \param NAME - The name of the standard.
+/// \param DESC - A short description of the standard.
+/// \param FEATURES - The standard features as flags, these are enums from the
+/// clang::frontend namespace, which is assumed to be be available.
+
+// C89-ish modes.
+LANGSTANDARD(c89, "c89",
+ "ISO C 1990",
+ ImplicitInt)
+LANGSTANDARD(c90, "c90",
+ "ISO C 1990",
+ ImplicitInt)
+LANGSTANDARD(iso9899_1990, "iso9899:1990",
+ "ISO C 1990",
+ ImplicitInt)
+
+LANGSTANDARD(c94, "iso9899:199409",
+ "ISO C 1990 with amendment 1",
+ Digraphs | ImplicitInt)
+
+LANGSTANDARD(gnu89, "gnu89",
+ "ISO C 1990 with GNU extensions",
+ BCPLComment | Digraphs | GNUMode | ImplicitInt)
+
+// C99-ish modes
+LANGSTANDARD(c99, "c99",
+ "ISO C 1999",
+ BCPLComment | C99 | Digraphs | HexFloat)
+LANGSTANDARD(c9x, "c9x",
+ "ISO C 1999",
+ BCPLComment | C99 | Digraphs | HexFloat)
+LANGSTANDARD(iso9899_1999,
+ "iso9899:1999", "ISO C 1999",
+ BCPLComment | C99 | Digraphs | HexFloat)
+LANGSTANDARD(iso9899_199x,
+ "iso9899:199x", "ISO C 1999",
+ BCPLComment | C99 | Digraphs | HexFloat)
+
+LANGSTANDARD(gnu99, "gnu99",
+ "ISO C 1999 with GNU extensions",
+ BCPLComment | C99 | Digraphs | GNUMode | HexFloat | Digraphs)
+LANGSTANDARD(gnu9x, "gnu9x",
+ "ISO C 1999 with GNU extensions",
+ BCPLComment | C99 | Digraphs | GNUMode | HexFloat)
+
+// C++ modes
+LANGSTANDARD(cxx98, "c++98",
+ "ISO C++ 1998 with amendments",
+ BCPLComment | CPlusPlus | Digraphs)
+LANGSTANDARD(gnucxx98, "gnu++98",
+ "ISO C++ 1998 with " "amendments and GNU extensions",
+ BCPLComment | CPlusPlus | Digraphs | GNUMode)
+
+LANGSTANDARD(cxx0x, "c++0x",
+ "Upcoming ISO C++ 200x with amendments",
+ BCPLComment | CPlusPlus | CPlusPlus0x | Digraphs)
+LANGSTANDARD(gnucxx0x, "gnu++0x",
+ "Upcoming ISO C++ 200x with amendments and GNU extensions",
+ BCPLComment | CPlusPlus | CPlusPlus0x | Digraphs | GNUMode)
+
+// OpenCL
+
+LANGSTANDARD(opencl, "cl",
+ "OpenCL 1.0",
+ BCPLComment | C99 | Digraphs | HexFloat)
+
+#undef LANGSTANDARD
diff --git a/include/clang/Frontend/PCHBitCodes.h b/include/clang/Frontend/PCHBitCodes.h
index b2bb9a1..98463c3 100644
--- a/include/clang/Frontend/PCHBitCodes.h
+++ b/include/clang/Frontend/PCHBitCodes.h
@@ -336,7 +336,9 @@ namespace clang {
/// \brief The ObjC 'id' type.
PREDEF_TYPE_OBJC_ID = 26,
/// \brief The ObjC 'Class' type.
- PREDEF_TYPE_OBJC_CLASS = 27
+ PREDEF_TYPE_OBJC_CLASS = 27,
+ /// \brief The ObjC 'SEL' type.
+ PREDEF_TYPE_OBJC_SEL = 28
};
/// \brief The number of predefined type IDs that are reserved for
@@ -438,7 +440,9 @@ namespace clang {
/// \brief Block descriptor type for Blocks CodeGen
SPECIAL_TYPE_BLOCK_DESCRIPTOR = 12,
/// \brief Block extedned descriptor type for Blocks CodeGen
- SPECIAL_TYPE_BLOCK_EXTENDED_DESCRIPTOR = 13
+ SPECIAL_TYPE_BLOCK_EXTENDED_DESCRIPTOR = 13,
+ /// \brief Objective-C "SEL" redefinition type
+ SPECIAL_TYPE_OBJC_SEL_REDEFINITION = 14
};
/// \brief Record codes for each kind of declaration.
diff --git a/include/clang/Frontend/PathDiagnosticClients.h b/include/clang/Frontend/PathDiagnosticClients.h
index 98831ba..f8d2eeb 100644
--- a/include/clang/Frontend/PathDiagnosticClients.h
+++ b/include/clang/Frontend/PathDiagnosticClients.h
@@ -14,9 +14,7 @@
#ifndef LLVM_CLANG_FRONTEND_PATH_DIAGNOSTIC_CLIENTS_H
#define LLVM_CLANG_FRONTEND_PATH_DIAGNOSTIC_CLiENTS_H
-#include <memory>
#include <string>
-#include "llvm/ADT/SmallVector.h"
namespace clang {
diff --git a/include/clang/Frontend/StmtXML.def b/include/clang/Frontend/StmtXML.def
index fd79cf0..2f0da9e 100644
--- a/include/clang/Frontend/StmtXML.def
+++ b/include/clang/Frontend/StmtXML.def
@@ -7,46 +7,46 @@
//
//===----------------------------------------------------------------------===//
//
-// This file defines the XML statement database structure as written in
-// <TranslationUnit> sub-nodes of the XML document.
+// This file defines the XML statement database structure as written in
+// <TranslationUnit> sub-nodes of the XML document.
// The semantics of the attributes and enums are mostly self-documenting
// by looking at the appropriate internally used functions and values.
// The following macros are used:
//
-// NODE_XML( CLASS, NAME ) - A node of name NAME denotes a concrete
-// statement of class CLASS where CLASS is a class name used internally by clang.
-// After a NODE_XML the definition of all (optional) attributes of that statement
+// NODE_XML( CLASS, NAME ) - A node of name NAME denotes a concrete
+// statement of class CLASS where CLASS is a class name used internally by clang.
+// After a NODE_XML the definition of all (optional) attributes of that statement
// node and possible sub-nodes follows.
//
// END_NODE_XML - Closes the attribute definition of the current node.
//
-// ID_ATTRIBUTE_XML - Some statement nodes have an "id" attribute containing a
-// string, which value uniquely identify that statement. Other nodes may refer
+// ID_ATTRIBUTE_XML - Some statement nodes have an "id" attribute containing a
+// string, which value uniquely identify that statement. Other nodes may refer
// by reference attributes to this value (currently used only for Label).
//
// TYPE_ATTRIBUTE_XML( FN ) - Type nodes refer to the result type id of an
// expression by a "type" attribute. FN is internally used by clang.
-//
-// ATTRIBUTE_XML( FN, NAME ) - An attribute named NAME. FN is internally
+//
+// ATTRIBUTE_XML( FN, NAME ) - An attribute named NAME. FN is internally
// used by clang. A boolean attribute have the values "0" or "1".
//
-// ATTRIBUTE_SPECIAL_XML( FN, NAME ) - An attribute named NAME which deserves
-// a special handling. See the appropriate documentations.
+// ATTRIBUTE_SPECIAL_XML( FN, NAME ) - An attribute named NAME which deserves
+// a special handling. See the appropriate documentations.
//
// ATTRIBUTE_FILE_LOCATION_XML - A bunch of attributes denoting the location of
// a statement in the source file(s).
//
-// ATTRIBUTE_OPT_XML( FN, NAME ) - An optional attribute named NAME.
-// Optional attributes are omitted for boolean types, if the value is false,
-// for integral types, if the value is null and for strings,
+// ATTRIBUTE_OPT_XML( FN, NAME ) - An optional attribute named NAME.
+// Optional attributes are omitted for boolean types, if the value is false,
+// for integral types, if the value is null and for strings,
// if the value is the empty string. FN is internally used by clang.
//
// ATTRIBUTE_ENUM[_OPT]_XML( FN, NAME ) - An attribute named NAME. The value
-// is an enumeration defined with ENUM_XML macros immediately following after
-// that macro. An optional attribute is ommited, if the particular enum is the
+// is an enumeration defined with ENUM_XML macros immediately following after
+// that macro. An optional attribute is ommited, if the particular enum is the
// empty string. FN is internally used by clang.
-//
-// ENUM_XML( VALUE, NAME ) - An enumeration element named NAME. VALUE is
+//
+// ENUM_XML( VALUE, NAME ) - An enumeration element named NAME. VALUE is
// internally used by clang.
//
// END_ENUM_XML - Closes the enumeration definition of the current attribute.
@@ -55,7 +55,7 @@
//
// SUB_NODE_OPT_XML( CLASS ) - An optional sub-node of class CLASS or its sub-classes.
//
-// SUB_NODE_SEQUENCE_XML( CLASS ) - Zero or more sub-nodes of class CLASS or
+// SUB_NODE_SEQUENCE_XML( CLASS ) - Zero or more sub-nodes of class CLASS or
// its sub-classes.
//
//===----------------------------------------------------------------------===//
@@ -94,21 +94,21 @@ END_NODE_XML
NODE_XML(CaseStmt, "CaseStmt") // case expr: body;
ATTRIBUTE_FILE_LOCATION_XML
- SUB_NODE_XML(Stmt) // body
+ SUB_NODE_XML(Stmt) // body
SUB_NODE_XML(Expr) // expr
SUB_NODE_XML(Expr) // rhs expr in gc extension: case expr .. expr: body;
END_NODE_XML
NODE_XML(DefaultStmt, "DefaultStmt") // default: body;
ATTRIBUTE_FILE_LOCATION_XML
- SUB_NODE_XML(Stmt) // body
+ SUB_NODE_XML(Stmt) // body
END_NODE_XML
NODE_XML(LabelStmt, "LabelStmt") // Label: body;
ID_ATTRIBUTE_XML
ATTRIBUTE_FILE_LOCATION_XML
ATTRIBUTE_XML(getName(), "name") // string
- SUB_NODE_XML(Stmt) // body
+ SUB_NODE_XML(Stmt) // body
END_NODE_XML
NODE_XML(IfStmt, "IfStmt") // if (cond) stmt1; else stmt2;
@@ -173,23 +173,23 @@ NODE_XML(AsmStmt, "AsmStmt") // GNU inline-assembly sta
// FIXME
END_NODE_XML
-NODE_XML(DeclStmt, "DeclStmt") // a declaration statement
+NODE_XML(DeclStmt, "DeclStmt") // a declaration statement
ATTRIBUTE_FILE_LOCATION_XML
- SUB_NODE_SEQUENCE_XML(Decl)
+ SUB_NODE_SEQUENCE_XML(Decl)
END_NODE_XML
// C++ statements
NODE_XML(CXXTryStmt, "CXXTryStmt") // try CompoundStmt CXXCatchStmt1 CXXCatchStmt2 ..
ATTRIBUTE_FILE_LOCATION_XML
ATTRIBUTE_XML(getNumHandlers(), "num_handlers")
- SUB_NODE_XML(CompoundStmt)
- SUB_NODE_SEQUENCE_XML(CXXCatchStmt)
+ SUB_NODE_XML(CompoundStmt)
+ SUB_NODE_SEQUENCE_XML(CXXCatchStmt)
END_NODE_XML
NODE_XML(CXXCatchStmt, "CXXCatchStmt") // catch (decl) Stmt
ATTRIBUTE_FILE_LOCATION_XML
SUB_NODE_XML(VarDecl)
- SUB_NODE_XML(Stmt)
+ SUB_NODE_XML(Stmt)
END_NODE_XML
// Expressions
@@ -234,7 +234,7 @@ NODE_XML(StringLiteral, "StringLiteral")
ATTRIBUTE_FILE_LOCATION_XML
TYPE_ATTRIBUTE_XML(getType())
ATTRIBUTE_SPECIAL_XML(getStrData(), "value") // string, special handling for escaping needed
- ATTRIBUTE_OPT_XML(isWide(), "is_wide") // boolean
+ ATTRIBUTE_OPT_XML(isWide(), "is_wide") // boolean
END_NODE_XML
NODE_XML(UnaryOperator, "UnaryOperator") // op(expr) or (expr)op
@@ -251,7 +251,7 @@ NODE_XML(UnaryOperator, "UnaryOperator") // op(expr) or (expr)op
ENUM_XML(UnaryOperator::Minus, "minus")
ENUM_XML(UnaryOperator::Not, "not") // bitwise not
ENUM_XML(UnaryOperator::LNot, "lnot") // boolean not
- ENUM_XML(UnaryOperator::Real, "__real")
+ ENUM_XML(UnaryOperator::Real, "__real")
ENUM_XML(UnaryOperator::Imag, "__imag")
ENUM_XML(UnaryOperator::Extension, "__extension__")
ENUM_XML(UnaryOperator::OffsetOf, "__builtin_offsetof")
@@ -314,7 +314,7 @@ END_NODE_XML
NODE_XML(SizeOfAlignOfExpr, "SizeOfAlignOfExpr") // sizeof(expr) or alignof(expr)
ATTRIBUTE_FILE_LOCATION_XML
TYPE_ATTRIBUTE_XML(getType())
- ATTRIBUTE_XML(isSizeOf(), "is_sizeof")
+ ATTRIBUTE_XML(isSizeOf(), "is_sizeof")
ATTRIBUTE_XML(isArgumentType(), "is_type") // "1" if expr denotes a type
ATTRIBUTE_SPECIAL_XML(getArgumentType(), "type_ref") // optional, denotes the type of expr, if is_type=="1", special handling needed since getArgumentType() could assert
SUB_NODE_OPT_XML(Expr) // expr, if is_type=="0"
@@ -346,29 +346,29 @@ END_NODE_XML
NODE_XML(CStyleCastExpr, "CStyleCastExpr") // (type)expr
ATTRIBUTE_FILE_LOCATION_XML
- TYPE_ATTRIBUTE_XML(getType())
+ TYPE_ATTRIBUTE_XML(getType())
ATTRIBUTE_XML(getTypeAsWritten(), "type_ref") // denotes the type as written in the source code
SUB_NODE_XML(Expr) // expr
END_NODE_XML
NODE_XML(ImplicitCastExpr, "ImplicitCastExpr")
ATTRIBUTE_FILE_LOCATION_XML
- TYPE_ATTRIBUTE_XML(getType())
- SUB_NODE_XML(Expr)
+ TYPE_ATTRIBUTE_XML(getType())
+ SUB_NODE_XML(Expr)
END_NODE_XML
-NODE_XML(CompoundLiteralExpr, "CompoundLiteralExpr") // [C99 6.5.2.5]
+NODE_XML(CompoundLiteralExpr, "CompoundLiteralExpr") // [C99 6.5.2.5]
SUB_NODE_XML(Expr) // init
END_NODE_XML
NODE_XML(ExtVectorElementExpr, "ExtVectorElementExpr")
- SUB_NODE_XML(Expr) // base
+ SUB_NODE_XML(Expr) // base
END_NODE_XML
NODE_XML(InitListExpr, "InitListExpr") // struct foo x = { expr1, { expr2, expr3 } };
ATTRIBUTE_FILE_LOCATION_XML
TYPE_ATTRIBUTE_XML(getType())
- ATTRIBUTE_OPT_XML(getInitializedFieldInUnion(), "field_ref") // if a union is initialized, this refers to the initialized union field id
+ ATTRIBUTE_OPT_XML(getInitializedFieldInUnion(), "field_ref") // if a union is initialized, this refers to the initialized union field id
ATTRIBUTE_XML(getNumInits(), "num_inits") // unsigned
SUB_NODE_SEQUENCE_XML(Expr) // expr1..exprN
END_NODE_XML
@@ -412,8 +412,8 @@ END_NODE_XML
NODE_XML(TypesCompatibleExpr, "TypesCompatibleExpr") // GNU builtin-in function __builtin_types_compatible_p
ATTRIBUTE_FILE_LOCATION_XML
TYPE_ATTRIBUTE_XML(getType())
- ATTRIBUTE_XML(getArgType1(), "type1_ref") // id of type1
- ATTRIBUTE_XML(getArgType2(), "type2_ref") // id of type2
+ ATTRIBUTE_XML(getArgType1(), "type1_ref") // id of type1
+ ATTRIBUTE_XML(getArgType2(), "type2_ref") // id of type2
END_NODE_XML
NODE_XML(ChooseExpr, "ChooseExpr") // GNU builtin-in function __builtin_choose_expr(expr1, expr2, expr3)
@@ -495,16 +495,9 @@ NODE_XML(CXXDefaultArgExpr, "CXXDefaultArgExpr")
ATTRIBUTE_XML(getParam(), "ref") // id of the parameter declaration (the expression is a subnode of the declaration)
END_NODE_XML
-NODE_XML(CXXConditionDeclExpr, "CXXConditionDeclExpr")
- ATTRIBUTE_FILE_LOCATION_XML
- TYPE_ATTRIBUTE_XML(getType())
- SUB_NODE_XML(VarDecl) // a CXXConditionDeclExpr owns the declaration
-END_NODE_XML
-
-
//===----------------------------------------------------------------------===//
#undef NODE_XML
-#undef ID_ATTRIBUTE_XML
+#undef ID_ATTRIBUTE_XML
#undef TYPE_ATTRIBUTE_XML
#undef ATTRIBUTE_XML
#undef ATTRIBUTE_SPECIAL_XML
@@ -513,8 +506,8 @@ END_NODE_XML
#undef ATTRIBUTE_ENUM_OPT_XML
#undef ATTRIBUTE_FILE_LOCATION_XML
#undef ENUM_XML
-#undef END_ENUM_XML
-#undef END_NODE_XML
+#undef END_ENUM_XML
+#undef END_NODE_XML
#undef SUB_NODE_XML
#undef SUB_NODE_SEQUENCE_XML
#undef SUB_NODE_OPT_XML
diff --git a/include/clang/Frontend/TextDiagnosticBuffer.h b/include/clang/Frontend/TextDiagnosticBuffer.h
index 4e907e1..380a1dd 100644
--- a/include/clang/Frontend/TextDiagnosticBuffer.h
+++ b/include/clang/Frontend/TextDiagnosticBuffer.h
@@ -41,6 +41,10 @@ public:
virtual void HandleDiagnostic(Diagnostic::Level DiagLevel,
const DiagnosticInfo &Info);
+
+ /// FlushDiagnostics - Flush the buffered diagnostics to an given
+ /// diagnostic engine.
+ void FlushDiagnostics(Diagnostic &Diags) const;
};
} // end namspace clang
diff --git a/include/clang/Lex/Lexer.h b/include/clang/Lex/Lexer.h
index c2db4d3..52bf194 100644
--- a/include/clang/Lex/Lexer.h
+++ b/include/clang/Lex/Lexer.h
@@ -78,7 +78,7 @@ public:
/// with the specified preprocessor managing the lexing process. This lexer
/// assumes that the associated file buffer and Preprocessor objects will
/// outlive it, so it doesn't take ownership of either of them.
- Lexer(FileID FID, Preprocessor &PP);
+ Lexer(FileID FID, const llvm::MemoryBuffer *InputBuffer, Preprocessor &PP);
/// Lexer constructor - Create a new raw lexer object. This object is only
/// suitable for calls to 'LexRawToken'. This lexer assumes that the text
@@ -89,7 +89,8 @@ public:
/// Lexer constructor - Create a new raw lexer object. This object is only
/// suitable for calls to 'LexRawToken'. This lexer assumes that the text
/// range will outlive it, so it doesn't take ownership of it.
- Lexer(FileID FID, const SourceManager &SM, const LangOptions &Features);
+ Lexer(FileID FID, const llvm::MemoryBuffer *InputBuffer,
+ const SourceManager &SM, const LangOptions &Features);
/// Create_PragmaLexer: Lexer constructor - Create a new lexer object for
/// _Pragma expansion. This has a variety of magic semantics that this method
diff --git a/include/clang/Lex/Preprocessor.h b/include/clang/Lex/Preprocessor.h
index 1c0036e..edd34b7 100644
--- a/include/clang/Lex/Preprocessor.h
+++ b/include/clang/Lex/Preprocessor.h
@@ -329,9 +329,9 @@ public:
void EnterMainSourceFile();
/// EnterSourceFile - Add a source file to the top of the include stack and
- /// start lexing tokens from it instead of the current buffer. If isMainFile
- /// is true, this is the main file for the translation unit.
- void EnterSourceFile(FileID CurFileID, const DirectoryLookup *Dir);
+ /// start lexing tokens from it instead of the current buffer. Return true
+ /// on failure.
+ bool EnterSourceFile(FileID CurFileID, const DirectoryLookup *Dir);
/// 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
diff --git a/include/clang/Parse/Action.h b/include/clang/Parse/Action.h
index 3d3232b..fc56cc6 100644
--- a/include/clang/Parse/Action.h
+++ b/include/clang/Parse/Action.h
@@ -203,11 +203,15 @@ public:
/// this occurs when deriving from "std::vector<T>::allocator_type", where T
/// is a template parameter.
///
+ /// \param ObjectType if we're checking whether an identifier is a type
+ /// within a C++ member access expression, this will be the type of the
+ ///
/// \returns the type referred to by this identifier, or NULL if the type
/// does not name an identifier.
virtual TypeTy *getTypeName(IdentifierInfo &II, SourceLocation NameLoc,
Scope *S, const CXXScopeSpec *SS = 0,
- bool isClassName = false) = 0;
+ bool isClassName = false,
+ TypeTy *ObjectType = 0) = 0;
/// isTagName() - This method is called *for error recovery purposes only*
/// to determine if the specified name is a valid tag name ("struct foo"). If
@@ -668,6 +672,9 @@ public:
return StmtEmpty();
}
+ virtual void ActOnForEachDeclStmt(DeclGroupPtrTy Decl) {
+ }
+
virtual OwningStmtResult ActOnExprStmt(FullExprArg Expr) {
return OwningStmtResult(*this, Expr->release());
}
@@ -698,14 +705,39 @@ public:
return StmtEmpty();
}
+ /// \brief Parsed an "if" statement.
+ ///
+ /// \param IfLoc the location of the "if" keyword.
+ ///
+ /// \param CondVal if the "if" condition was parsed as an expression,
+ /// the expression itself.
+ ///
+ /// \param CondVar if the "if" condition was parsed as a condition variable,
+ /// the condition variable itself.
+ ///
+ /// \param ThenVal the "then" statement.
+ ///
+ /// \param ElseLoc the location of the "else" keyword.
+ ///
+ /// \param ElseVal the "else" statement.
virtual OwningStmtResult ActOnIfStmt(SourceLocation IfLoc,
- FullExprArg CondVal, StmtArg ThenVal,
+ FullExprArg CondVal,
+ DeclPtrTy CondVar,
+ StmtArg ThenVal,
SourceLocation ElseLoc,
StmtArg ElseVal) {
return StmtEmpty();
}
- virtual OwningStmtResult ActOnStartOfSwitchStmt(ExprArg Cond) {
+ /// \brief Parsed the start of a "switch" statement.
+ ///
+ /// \param Cond if the "switch" condition was parsed as an expression,
+ /// the expression itself.
+ ///
+ /// \param CondVar if the "switch" condition was parsed as a condition
+ /// variable, the condition variable itself.
+ virtual OwningStmtResult ActOnStartOfSwitchStmt(FullExprArg Cond,
+ DeclPtrTy CondVar) {
return StmtEmpty();
}
@@ -714,8 +746,18 @@ public:
return StmtEmpty();
}
+ /// \brief Parsed a "while" statement.
+ ///
+ /// \param Cond if the "while" condition was parsed as an expression,
+ /// the expression itself.
+ ///
+ /// \param CondVar if the "while" condition was parsed as a condition
+ /// variable, the condition variable itself.
+ ///
+ /// \param Body the body of the "while" loop.
virtual OwningStmtResult ActOnWhileStmt(SourceLocation WhileLoc,
- FullExprArg Cond, StmtArg Body) {
+ FullExprArg Cond, DeclPtrTy CondVar,
+ StmtArg Body) {
return StmtEmpty();
}
virtual OwningStmtResult ActOnDoStmt(SourceLocation DoLoc, StmtArg Body,
@@ -725,13 +767,36 @@ public:
SourceLocation CondRParen) {
return StmtEmpty();
}
+
+ /// \brief Parsed a "for" statement.
+ ///
+ /// \param ForLoc the location of the "for" keyword.
+ ///
+ /// \param LParenLoc the location of the left parentheses.
+ ///
+ /// \param First the statement used to initialize the for loop.
+ ///
+ /// \param Second the condition to be checked during each iteration, if
+ /// that condition was parsed as an expression.
+ ///
+ /// \param SecondArg the condition variable to be checked during each
+ /// iterator, if that condition was parsed as a variable declaration.
+ ///
+ /// \param Third the expression that will be evaluated to "increment" any
+ /// values prior to the next iteration.
+ ///
+ /// \param RParenLoc the location of the right parentheses.
+ ///
+ /// \param Body the body of the "body" loop.
virtual OwningStmtResult ActOnForStmt(SourceLocation ForLoc,
SourceLocation LParenLoc,
- StmtArg First, ExprArg Second,
- ExprArg Third, SourceLocation RParenLoc,
+ StmtArg First, FullExprArg Second,
+ DeclPtrTy SecondVar, FullExprArg Third,
+ SourceLocation RParenLoc,
StmtArg Body) {
return StmtEmpty();
}
+
virtual OwningStmtResult ActOnObjCForCollectionStmt(SourceLocation ForColLoc,
SourceLocation LParenLoc,
StmtArg First, ExprArg Second,
@@ -852,23 +917,12 @@ public:
/// \brief The parser is entering a new expression evaluation context.
///
/// \param NewContext is the new expression evaluation context.
- ///
- /// \returns the previous expression evaluation context.
- virtual ExpressionEvaluationContext
- PushExpressionEvaluationContext(ExpressionEvaluationContext NewContext) {
- return PotentiallyEvaluated;
- }
+ virtual void
+ PushExpressionEvaluationContext(ExpressionEvaluationContext NewContext) { }
- /// \brief The parser is existing an expression evaluation context.
- ///
- /// \param OldContext the expression evaluation context that the parser is
- /// leaving.
- ///
- /// \param NewContext the expression evaluation context that the parser is
- /// returning to.
+ /// \brief The parser is exiting an expression evaluation context.
virtual void
- PopExpressionEvaluationContext(ExpressionEvaluationContext OldContext,
- ExpressionEvaluationContext NewContext) { }
+ PopExpressionEvaluationContext() { }
// Primary Expressions.
@@ -927,9 +981,10 @@ public:
return move(Val); // Default impl returns operand.
}
- virtual OwningExprResult ActOnParenListExpr(SourceLocation L,
+ virtual OwningExprResult ActOnParenOrParenListExpr(SourceLocation L,
SourceLocation R,
- MultiExprArg Val) {
+ MultiExprArg Val,
+ TypeTy *TypeOfCast=0) {
return ExprEmpty();
}
@@ -1041,6 +1096,10 @@ public:
return ExprEmpty();
}
+ virtual bool TypeIsVectorType(TypeTy *Ty) {
+ return false;
+ }
+
virtual OwningExprResult ActOnBinOp(Scope *S, SourceLocation TokLoc,
tok::TokenKind Kind,
ExprArg LHS, ExprArg RHS) {
@@ -1371,15 +1430,22 @@ public:
return ExprEmpty();
}
- /// ActOnCXXConditionDeclarationExpr - Parsed a condition declaration of a
- /// C++ if/switch/while/for statement.
- /// e.g: "if (int x = f()) {...}"
- virtual OwningExprResult ActOnCXXConditionDeclarationExpr(Scope *S,
- SourceLocation StartLoc,
- Declarator &D,
- SourceLocation EqualLoc,
- ExprArg AssignExprVal) {
- return ExprEmpty();
+ /// \brief Parsed a condition declaration in a C++ if, switch, or while
+ /// statement.
+ ///
+ /// This callback will be invoked after parsing the declaration of "x" in
+ ///
+ /// \code
+ /// if (int x = f()) {
+ /// // ...
+ /// }
+ /// \endcode
+ ///
+ /// \param S the scope of the if, switch, or while statement.
+ ///
+ /// \param D the declarator that that describes the variable being declared.
+ virtual DeclResult ActOnCXXConditionDeclaration(Scope *S, Declarator &D) {
+ return DeclResult();
}
/// ActOnCXXNew - Parsed a C++ 'new' expression. UseGlobal is true if the
@@ -1470,6 +1536,7 @@ public:
MultiTemplateParamsArg TemplateParameterLists,
ExprTy *BitfieldWidth,
ExprTy *Init,
+ bool IsDefinition,
bool Deleted = false) {
return DeclPtrTy();
}
@@ -1678,10 +1745,14 @@ public:
/// \param ObjectType if this dependent template name occurs in the
/// context of a member access expression, the type of the object being
/// accessed.
+ ///
+ /// \param EnteringContext whether we are entering the context of this
+ /// template.
virtual TemplateTy ActOnDependentTemplateName(SourceLocation TemplateKWLoc,
const CXXScopeSpec &SS,
UnqualifiedId &Name,
- TypeTy *ObjectType) {
+ TypeTy *ObjectType,
+ bool EnteringContext) {
return TemplateTy();
}
@@ -2515,7 +2586,8 @@ public:
/// does not name an identifier.
virtual TypeTy *getTypeName(IdentifierInfo &II, SourceLocation NameLoc,
Scope *S, const CXXScopeSpec *SS,
- bool isClassName = false);
+ bool isClassName = false,
+ TypeTy *ObjectType = 0);
/// isCurrentClassName - Always returns false, because MinimalAction
/// does not support C++ classes with constructors.
@@ -2578,21 +2650,15 @@ class EnterExpressionEvaluationContext {
/// \brief The action object.
Action &Actions;
- /// \brief The previous expression evaluation context.
- Action::ExpressionEvaluationContext PrevContext;
-
- /// \brief The current expression evaluation context.
- Action::ExpressionEvaluationContext CurContext;
-
public:
EnterExpressionEvaluationContext(Action &Actions,
Action::ExpressionEvaluationContext NewContext)
- : Actions(Actions), CurContext(NewContext) {
- PrevContext = Actions.PushExpressionEvaluationContext(NewContext);
+ : Actions(Actions) {
+ Actions.PushExpressionEvaluationContext(NewContext);
}
~EnterExpressionEvaluationContext() {
- Actions.PopExpressionEvaluationContext(CurContext, PrevContext);
+ Actions.PopExpressionEvaluationContext();
}
};
diff --git a/include/clang/Parse/AttributeList.h b/include/clang/Parse/AttributeList.h
index 81bb300..ecaa6ae 100644
--- a/include/clang/Parse/AttributeList.h
+++ b/include/clang/Parse/AttributeList.h
@@ -33,19 +33,22 @@ namespace clang {
class AttributeList {
IdentifierInfo *AttrName;
SourceLocation AttrLoc;
+ IdentifierInfo *ScopeName;
+ SourceLocation ScopeLoc;
IdentifierInfo *ParmName;
SourceLocation ParmLoc;
ActionBase::ExprTy **Args;
unsigned NumArgs;
AttributeList *Next;
- bool DeclspecAttribute;
+ bool DeclspecAttribute, CXX0XAttribute;
AttributeList(const AttributeList &); // DO NOT IMPLEMENT
void operator=(const AttributeList &); // DO NOT IMPLEMENT
public:
AttributeList(IdentifierInfo *AttrName, SourceLocation AttrLoc,
+ IdentifierInfo *ScopeName, SourceLocation ScopeLoc,
IdentifierInfo *ParmName, SourceLocation ParmLoc,
ActionBase::ExprTy **args, unsigned numargs,
- AttributeList *Next, bool declspec = false);
+ AttributeList *Next, bool declspec = false, bool cxx0x = false);
~AttributeList();
enum Kind { // Please keep this list alphabetized.
@@ -56,7 +59,9 @@ public:
AT_always_inline,
AT_analyzer_noreturn,
AT_annotate,
+ AT_base_check,
AT_blocks,
+ AT_carries_dependency,
AT_cdecl,
AT_cleanup,
AT_const,
@@ -67,9 +72,11 @@ public:
AT_dllimport,
AT_ext_vector_type,
AT_fastcall,
+ AT_final,
AT_format,
AT_format_arg,
AT_gnu_inline,
+ AT_hiding,
AT_malloc,
AT_mode,
AT_nodebug,
@@ -80,6 +87,7 @@ public:
AT_nothrow,
AT_nsobject,
AT_objc_exception,
+ AT_override,
AT_cf_returns_retained, // Clang-specific.
AT_ns_returns_retained, // Clang-specific.
AT_objc_gc,
@@ -106,8 +114,15 @@ public:
IdentifierInfo *getName() const { return AttrName; }
SourceLocation getLoc() const { return AttrLoc; }
+
+ bool hasScope() const { return ScopeName; }
+ IdentifierInfo *getScopeName() const { return ScopeName; }
+ SourceLocation getScopeLoc() const { return ScopeLoc; }
+
IdentifierInfo *getParameterName() const { return ParmName; }
+
bool isDeclspecAttribute() const { return DeclspecAttribute; }
+ bool isCXX0XAttribute() const { return CXX0XAttribute; }
Kind getKind() const { return getKind(getName()); }
static Kind getKind(const IdentifierInfo *Name);
@@ -181,6 +196,22 @@ inline AttributeList* addAttributeLists (AttributeList *Left,
return Left;
}
+/// CXX0XAttributeList - A wrapper around a C++0x attribute list.
+/// Stores, in addition to the list proper, whether or not an actual list was
+/// (as opposed to an empty list, which may be ill-formed in some places) and
+/// the source range of the list.
+struct CXX0XAttributeList {
+ AttributeList *AttrList;
+ SourceRange Range;
+ bool HasAttr;
+ CXX0XAttributeList (AttributeList *attrList, SourceRange range, bool hasAttr)
+ : AttrList(attrList), Range(range), HasAttr (hasAttr) {
+ }
+ CXX0XAttributeList ()
+ : AttrList(0), Range(), HasAttr(false) {
+ }
+};
+
} // end namespace clang
#endif
diff --git a/include/clang/Parse/DeclSpec.h b/include/clang/Parse/DeclSpec.h
index 7e7d0b3..fe899b3 100644
--- a/include/clang/Parse/DeclSpec.h
+++ b/include/clang/Parse/DeclSpec.h
@@ -484,6 +484,8 @@ public:
IK_OperatorFunctionId,
/// \brief A conversion function name, e.g., operator int.
IK_ConversionFunctionId,
+ /// \brief A user-defined literal name, e.g., operator "" _i.
+ IK_LiteralOperatorId,
/// \brief A constructor name.
IK_ConstructorName,
/// \brief A destructor name.
@@ -495,7 +497,8 @@ public:
/// \brief Anonymous union that holds extra data associated with the
/// parsed unqualified-id.
union {
- /// \brief When Kind == IK_Identifier, the parsed identifier.
+ /// \brief When Kind == IK_Identifier, the parsed identifier, or when Kind
+ /// == IK_UserLiteralId, the identifier suffix.
IdentifierInfo *Identifier;
/// \brief When Kind == IK_OperatorFunctionId, the overloaded operator
@@ -607,6 +610,22 @@ public:
EndLocation = EndLoc;
ConversionFunctionId = Ty;
}
+
+ /// \brief Specific that this unqualified-id was parsed as a
+ /// literal-operator-id.
+ ///
+ /// \param Id the parsed identifier.
+ ///
+ /// \param OpLoc the location of the 'operator' keyword.
+ ///
+ /// \param IdLoc the location of the identifier.
+ void setLiteralOperatorId(const IdentifierInfo *Id, SourceLocation OpLoc,
+ SourceLocation IdLoc) {
+ Kind = IK_LiteralOperatorId;
+ Identifier = const_cast<IdentifierInfo *>(Id);
+ StartLocation = OpLoc;
+ EndLocation = IdLoc;
+ }
/// \brief Specify that this unqualified-id was parsed as a constructor name.
///
diff --git a/include/clang/Parse/Parser.h b/include/clang/Parse/Parser.h
index f7cccca..81a80eb 100644
--- a/include/clang/Parse/Parser.h
+++ b/include/clang/Parse/Parser.h
@@ -24,6 +24,7 @@
namespace clang {
class AttributeList;
+ struct CXX0XAttributeList;
class PragmaHandler;
class Scope;
class DiagnosticBuilder;
@@ -753,10 +754,10 @@ private:
//===--------------------------------------------------------------------===//
// C99 6.9: External Definitions.
- DeclGroupPtrTy ParseExternalDeclaration();
+ DeclGroupPtrTy ParseExternalDeclaration(CXX0XAttributeList Attr);
bool isDeclarationAfterDeclarator();
bool isStartOfFunctionDefinition();
- DeclGroupPtrTy ParseDeclarationOrFunctionDefinition(
+ DeclGroupPtrTy ParseDeclarationOrFunctionDefinition(AttributeList *Attr,
AccessSpecifier AS = AS_none);
DeclPtrTy ParseFunctionDefinition(ParsingDeclarator &D,
@@ -832,10 +833,10 @@ private:
OwningExprResult ParseCastExpression(bool isUnaryExpression,
bool isAddressOfOperand,
bool &NotCastExpr,
- bool parseParenAsExprList);
+ TypeTy *TypeOfCast);
OwningExprResult ParseCastExpression(bool isUnaryExpression,
bool isAddressOfOperand = false,
- bool parseParenAsExprList = false);
+ TypeTy *TypeOfCast = 0);
OwningExprResult ParsePostfixExpressionSuffix(OwningExprResult LHS);
OwningExprResult ParseSizeofAlignofExpression();
OwningExprResult ParseBuiltinPrimaryExpression();
@@ -865,7 +866,7 @@ private:
};
OwningExprResult ParseParenExpression(ParenParseOption &ExprType,
bool stopIfCastExpr,
- bool parseAsExprList,
+ TypeTy *TypeOfCast,
TypeTy *&CastTy,
SourceLocation &RParenLoc);
@@ -933,8 +934,8 @@ private:
SourceLocation Start);
//===--------------------------------------------------------------------===//
- // C++ if/switch/while/for condition expression.
- OwningExprResult ParseCXXCondition();
+ // C++ if/switch/while condition expression.
+ bool ParseCXXCondition(OwningExprResult &ExprResult, DeclPtrTy &DeclResult);
//===--------------------------------------------------------------------===//
// C++ types
@@ -994,24 +995,23 @@ private:
return ParseStatementOrDeclaration(true);
}
OwningStmtResult ParseStatementOrDeclaration(bool OnlyStatement = false);
- OwningStmtResult ParseLabeledStatement();
- OwningStmtResult ParseCaseStatement();
- OwningStmtResult ParseDefaultStatement();
- OwningStmtResult ParseCompoundStatement(bool isStmtExpr = false);
+ OwningStmtResult ParseLabeledStatement(AttributeList *Attr);
+ OwningStmtResult ParseCaseStatement(AttributeList *Attr);
+ OwningStmtResult ParseDefaultStatement(AttributeList *Attr);
+ OwningStmtResult ParseCompoundStatement(AttributeList *Attr,
+ bool isStmtExpr = false);
OwningStmtResult ParseCompoundStatementBody(bool isStmtExpr = false);
- bool ParseParenExprOrCondition(OwningExprResult &CondExp,
- bool OnlyAllowCondition = false,
- SourceLocation *LParenLoc = 0,
- SourceLocation *RParenLoc = 0);
- OwningStmtResult ParseIfStatement();
- OwningStmtResult ParseSwitchStatement();
- OwningStmtResult ParseWhileStatement();
- OwningStmtResult ParseDoStatement();
- OwningStmtResult ParseForStatement();
- OwningStmtResult ParseGotoStatement();
- OwningStmtResult ParseContinueStatement();
- OwningStmtResult ParseBreakStatement();
- OwningStmtResult ParseReturnStatement();
+ bool ParseParenExprOrCondition(OwningExprResult &ExprResult,
+ DeclPtrTy &DeclResult);
+ OwningStmtResult ParseIfStatement(AttributeList *Attr);
+ OwningStmtResult ParseSwitchStatement(AttributeList *Attr);
+ OwningStmtResult ParseWhileStatement(AttributeList *Attr);
+ OwningStmtResult ParseDoStatement(AttributeList *Attr);
+ OwningStmtResult ParseForStatement(AttributeList *Attr);
+ OwningStmtResult ParseGotoStatement(AttributeList *Attr);
+ OwningStmtResult ParseContinueStatement(AttributeList *Attr);
+ OwningStmtResult ParseBreakStatement(AttributeList *Attr);
+ OwningStmtResult ParseReturnStatement(AttributeList *Attr);
OwningStmtResult ParseAsmStatement(bool &msAsm);
OwningStmtResult FuzzyParseMicrosoftAsmStatement();
bool ParseAsmOperandsOpt(llvm::SmallVectorImpl<std::string> &Names,
@@ -1021,7 +1021,7 @@ private:
//===--------------------------------------------------------------------===//
// C++ 6: Statements and Blocks
- OwningStmtResult ParseCXXTryBlock();
+ OwningStmtResult ParseCXXTryBlock(AttributeList *Attr);
OwningStmtResult ParseCXXTryBlockCommon(SourceLocation TryLoc);
OwningStmtResult ParseCXXCatchBlock();
@@ -1045,9 +1045,11 @@ private:
DSC_class // class context, enables 'friend'
};
- DeclGroupPtrTy ParseDeclaration(unsigned Context, SourceLocation &DeclEnd);
+ DeclGroupPtrTy ParseDeclaration(unsigned Context, SourceLocation &DeclEnd,
+ CXX0XAttributeList Attr);
DeclGroupPtrTy ParseSimpleDeclaration(unsigned Context,
- SourceLocation &DeclEnd);
+ SourceLocation &DeclEnd,
+ AttributeList *Attr);
DeclGroupPtrTy ParseDeclGroup(ParsingDeclSpec &DS, unsigned Context,
bool AllowFunctionDefinitions,
SourceLocation *DeclEnd = 0);
@@ -1217,11 +1219,14 @@ private:
void ParseBlockId();
// EndLoc, if non-NULL, is filled with the location of the last token of
// the attribute list.
- AttributeList *ParseAttributes(SourceLocation *EndLoc = 0);
+ CXX0XAttributeList ParseCXX0XAttributes(SourceLocation *EndLoc = 0);
+ AttributeList *ParseGNUAttributes(SourceLocation *EndLoc = 0);
AttributeList *ParseMicrosoftDeclSpec(AttributeList* CurrAttr = 0);
AttributeList *ParseMicrosoftTypeAttributes(AttributeList* CurrAttr = 0);
void ParseTypeofSpecifier(DeclSpec &DS);
void ParseDecltypeSpecifier(DeclSpec &DS);
+
+ OwningExprResult ParseCXX0XAlignArgument(SourceLocation Start);
/// DeclaratorScopeObj - RAII object used in Parser::ParseDirectDeclarator to
/// enter a new C++ declarator scope and exit it when the function is
@@ -1265,7 +1270,8 @@ private:
typedef void (Parser::*DirectDeclParseFunction)(Declarator&);
void ParseDeclaratorInternal(Declarator &D,
DirectDeclParseFunction DirectDeclParser);
- void ParseTypeQualifierListOpt(DeclSpec &DS, bool AttributesAllowed = true);
+ void ParseTypeQualifierListOpt(DeclSpec &DS, bool GNUAttributesAllowed = true,
+ bool CXX0XAttributesAllowed = true);
void ParseDirectDeclarator(Declarator &D);
void ParseParenDeclarator(Declarator &D);
void ParseFunctionDeclarator(SourceLocation LParenLoc, Declarator &D,
@@ -1278,12 +1284,17 @@ private:
//===--------------------------------------------------------------------===//
// C++ 7: Declarations [dcl.dcl]
+ bool isCXX0XAttributeSpecifier(bool FullLookahead = false,
+ tok::TokenKind *After = 0);
+
DeclPtrTy ParseNamespace(unsigned Context, SourceLocation &DeclEnd);
DeclPtrTy ParseLinkage(unsigned Context);
DeclPtrTy ParseUsingDirectiveOrDeclaration(unsigned Context,
- SourceLocation &DeclEnd);
+ SourceLocation &DeclEnd,
+ CXX0XAttributeList Attrs);
DeclPtrTy ParseUsingDirective(unsigned Context, SourceLocation UsingLoc,
- SourceLocation &DeclEnd);
+ SourceLocation &DeclEnd,
+ AttributeList *Attr);
DeclPtrTy ParseUsingDeclaration(unsigned Context, SourceLocation UsingLoc,
SourceLocation &DeclEnd,
AccessSpecifier AS = AS_none);
@@ -1353,6 +1364,7 @@ private:
SourceLocation &RAngleLoc);
bool ParseTemplateParameterList(unsigned Depth,
TemplateParameterList &TemplateParams);
+ bool isStartOfTemplateTypeParameter();
DeclPtrTy ParseTemplateParameter(unsigned Depth, unsigned Position);
DeclPtrTy ParseTypeParameter(unsigned Depth, unsigned Position);
DeclPtrTy ParseTemplateTemplateParameter(unsigned Depth, unsigned Position);
diff --git a/include/clang/Sema/CodeCompleteConsumer.h b/include/clang/Sema/CodeCompleteConsumer.h
index ed74761..84c179f 100644
--- a/include/clang/Sema/CodeCompleteConsumer.h
+++ b/include/clang/Sema/CodeCompleteConsumer.h
@@ -209,7 +209,8 @@ public:
void Serialize(llvm::raw_ostream &OS) const;
/// \brief Deserialize a code-completion string from the given string.
- static CodeCompletionString *Deserialize(llvm::StringRef &Str);
+ static CodeCompletionString *Deserialize(const char *&Str,
+ const char *StrEnd);
};
llvm::raw_ostream &operator<<(llvm::raw_ostream &OS,
@@ -221,6 +222,10 @@ class CodeCompleteConsumer {
protected:
/// \brief Whether to include macros in the code-completion results.
bool IncludeMacros;
+
+ /// \brief Whether the output format for the code-completion consumer is
+ /// binary.
+ bool OutputIsBinary;
public:
/// \brief Captures a result of code completion.
@@ -394,17 +399,20 @@ public:
Sema &S) const;
};
- CodeCompleteConsumer() : IncludeMacros(false) { }
+ CodeCompleteConsumer() : IncludeMacros(false), OutputIsBinary(false) { }
- explicit CodeCompleteConsumer(bool IncludeMacros)
- : IncludeMacros(IncludeMacros) { }
+ CodeCompleteConsumer(bool IncludeMacros, bool OutputIsBinary)
+ : IncludeMacros(IncludeMacros), OutputIsBinary(OutputIsBinary) { }
/// \brief Whether the code-completion consumer wants to see macros.
bool includeMacros() const { return IncludeMacros; }
+
+ /// \brief Determine whether the output of this consumer is binary.
+ bool isOutputBinary() const { return OutputIsBinary; }
/// \brief Deregisters and destroys this code-completion consumer.
virtual ~CodeCompleteConsumer();
-
+
/// \name Code-completion callbacks
//@{
/// \brief Process the finalized code-completion results.
@@ -436,7 +444,7 @@ public:
/// results to the given raw output stream.
PrintingCodeCompleteConsumer(bool IncludeMacros,
llvm::raw_ostream &OS)
- : CodeCompleteConsumer(IncludeMacros), OS(OS) { }
+ : CodeCompleteConsumer(IncludeMacros, false), OS(OS) { }
/// \brief Prints the finalized code-completion results.
virtual void ProcessCodeCompleteResults(Sema &S, Result *Results,
@@ -458,7 +466,7 @@ public:
/// results to the given raw output stream in a format readable to the CIndex
/// library.
CIndexCodeCompleteConsumer(bool IncludeMacros, llvm::raw_ostream &OS)
- : CodeCompleteConsumer(IncludeMacros), OS(OS) { }
+ : CodeCompleteConsumer(IncludeMacros, true), OS(OS) { }
/// \brief Prints the finalized code-completion results.
virtual void ProcessCodeCompleteResults(Sema &S, Result *Results,
OpenPOWER on IntegriCloud